Compare commits
No commits in common. "7b4eeea12c1ebf3d8635605c07aeef62ff30efc9" and "885b9c7892b5ef39516048f74d20ff420e823eba" have entirely different histories.
7b4eeea12c
...
885b9c7892
|
@ -81,9 +81,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
version = "1.1.0"
|
version = "1.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "base64"
|
name = "base64"
|
||||||
|
@ -266,13 +266,22 @@ dependencies = [
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ct-logs"
|
||||||
|
version = "0.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c1a816186fa68d9e426e3cb4ae4dff1fcd8e4a2c34b781bf7a822574a0d0aac8"
|
||||||
|
dependencies = [
|
||||||
|
"sct 0.6.1",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ctrlc"
|
name = "ctrlc"
|
||||||
version = "3.2.1"
|
version = "3.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a19c6cedffdc8c03a3346d723eb20bd85a13362bb96dc2ac000842c6381ec7bf"
|
checksum = "a19c6cedffdc8c03a3346d723eb20bd85a13362bb96dc2ac000842c6381ec7bf"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"nix 0.23.1",
|
"nix",
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -636,9 +645,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "httparse"
|
name = "httparse"
|
||||||
version = "1.8.0"
|
version = "1.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904"
|
checksum = "acd94fdbe1d4ff688b67b04eee2e17bd50995534a61539e45adfefb45e5e5503"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "httpdate"
|
name = "httpdate"
|
||||||
|
@ -648,9 +657,9 @@ checksum = "6456b8a6c8f33fee7d958fcd1b60d55b11940a79e63ae87013e6d22e26034440"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hyper"
|
name = "hyper"
|
||||||
version = "0.14.20"
|
version = "0.14.13"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "02c929dc5c39e335a03c405292728118860721b10190d98c2a0f0efd5baafbac"
|
checksum = "15d1cfb9e4f68655fa04c01f59edb405b6074a0f7118ea881e5026e4a1cd8593"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
|
@ -661,9 +670,9 @@ dependencies = [
|
||||||
"http-body",
|
"http-body",
|
||||||
"httparse",
|
"httparse",
|
||||||
"httpdate",
|
"httpdate",
|
||||||
"itoa 1.0.1",
|
"itoa 0.4.8",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"socket2",
|
"socket2 0.4.4",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tower-service",
|
"tower-service",
|
||||||
"tracing",
|
"tracing",
|
||||||
|
@ -678,7 +687,7 @@ checksum = "d87c48c02e0dc5e3b849a2041db3029fd066650f8f717c07bf8ed78ccb895cac"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"http",
|
"http",
|
||||||
"hyper",
|
"hyper",
|
||||||
"rustls",
|
"rustls 0.20.4",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-rustls",
|
"tokio-rustls",
|
||||||
]
|
]
|
||||||
|
@ -717,18 +726,6 @@ dependencies = [
|
||||||
"hashbrown",
|
"hashbrown",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "insecure_chat"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"hyper",
|
|
||||||
"mac_address",
|
|
||||||
"nix 0.25.0",
|
|
||||||
"ptth_diceware",
|
|
||||||
"thiserror",
|
|
||||||
"tokio",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ipnet"
|
name = "ipnet"
|
||||||
version = "2.3.1"
|
version = "2.3.1"
|
||||||
|
@ -773,9 +770,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.135"
|
version = "0.2.122"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "68783febc7782c6c5cb401fbda4de5a9898be1762314da0bb2c10ced61f18b0c"
|
checksum = "ec647867e2bf0772e28c8bcde4f0d19a9216916e890543b5a03ed8ef27b8f259"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lock_api"
|
name = "lock_api"
|
||||||
|
@ -795,16 +792,6 @@ dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "mac_address"
|
|
||||||
version = "1.1.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b238e3235c8382b7653c6408ed1b08dd379bdb9fdf990fb0bbae3db2cc0ae963"
|
|
||||||
dependencies = [
|
|
||||||
"nix 0.23.1",
|
|
||||||
"winapi",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "maplit"
|
name = "maplit"
|
||||||
version = "1.0.2"
|
version = "1.0.2"
|
||||||
|
@ -857,14 +844,38 @@ checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mio"
|
name = "mio"
|
||||||
version = "0.8.4"
|
version = "0.7.13"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf"
|
checksum = "8c2bdb6314ec10835cd3293dd268473a835c02b7b352e788be788b3c6ca6bb16"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
|
"miow",
|
||||||
|
"ntapi",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mio"
|
||||||
|
version = "0.8.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "52da4364ffb0e4fe33a9841a98a3f3014fb964045ce4f7a45a398243c8d6b0c9"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"log",
|
||||||
|
"miow",
|
||||||
|
"ntapi",
|
||||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||||
"windows-sys 0.36.1",
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "miow"
|
||||||
|
version = "0.3.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21"
|
||||||
|
dependencies = [
|
||||||
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -887,9 +898,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nix"
|
name = "nix"
|
||||||
version = "0.23.1"
|
version = "0.23.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9f866317acbd3a240710c63f065ffb1e4fd466259045ccb504130b7f668f35c6"
|
checksum = "f305c2c2e4c39a82f7bf0bf65fb557f9070ce06781d4f2454295cc34b1c43188"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"cc",
|
"cc",
|
||||||
|
@ -899,17 +910,12 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nix"
|
name = "ntapi"
|
||||||
version = "0.25.0"
|
version = "0.3.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e322c04a9e3440c327fca7b6c8a63e6890a32fa2ad689db972425f07e0d22abb"
|
checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"winapi",
|
||||||
"bitflags",
|
|
||||||
"cfg-if",
|
|
||||||
"libc",
|
|
||||||
"memoffset",
|
|
||||||
"pin-utils",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1012,7 +1018,7 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"redox_syscall",
|
"redox_syscall",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"windows-sys 0.34.0",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1204,13 +1210,6 @@ dependencies = [
|
||||||
"tracing-futures",
|
"tracing-futures",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ptth_diceware"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"rand",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ptth_file_server"
|
name = "ptth_file_server"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
|
@ -1250,7 +1249,6 @@ dependencies = [
|
||||||
"ctrlc",
|
"ctrlc",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"hex",
|
"hex",
|
||||||
"ptth_diceware",
|
|
||||||
"ptth_file_server",
|
"ptth_file_server",
|
||||||
"ptth_quic",
|
"ptth_quic",
|
||||||
"ptth_server",
|
"ptth_server",
|
||||||
|
@ -1272,12 +1270,12 @@ dependencies = [
|
||||||
"ctrlc",
|
"ctrlc",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"hyper",
|
"hyper",
|
||||||
"quinn",
|
"quinn 0.8.5",
|
||||||
"rand",
|
"rand",
|
||||||
"rcgen",
|
"rcgen",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"rmp-serde",
|
"rmp-serde",
|
||||||
"rustls",
|
"rustls 0.20.4",
|
||||||
"structopt",
|
"structopt",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tracing",
|
"tracing",
|
||||||
|
@ -1292,7 +1290,7 @@ dependencies = [
|
||||||
"blake3",
|
"blake3",
|
||||||
"fltk",
|
"fltk",
|
||||||
"ptth_quic",
|
"ptth_quic",
|
||||||
"quinn",
|
"quinn 0.7.2",
|
||||||
"rand",
|
"rand",
|
||||||
"rand_chacha",
|
"rand_chacha",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
|
@ -1417,6 +1415,26 @@ version = "2.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3"
|
checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quinn"
|
||||||
|
version = "0.7.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c82c0a393b300104f989f3db8b8637c0d11f7a32a9c214560b47849ba8f119aa"
|
||||||
|
dependencies = [
|
||||||
|
"bytes",
|
||||||
|
"futures",
|
||||||
|
"lazy_static",
|
||||||
|
"libc",
|
||||||
|
"mio 0.7.13",
|
||||||
|
"quinn-proto 0.7.3",
|
||||||
|
"rustls 0.19.1",
|
||||||
|
"socket2 0.3.19",
|
||||||
|
"thiserror",
|
||||||
|
"tokio",
|
||||||
|
"tracing",
|
||||||
|
"webpki 0.21.4",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quinn"
|
name = "quinn"
|
||||||
version = "0.8.5"
|
version = "0.8.5"
|
||||||
|
@ -1427,13 +1445,32 @@ dependencies = [
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"fxhash",
|
"fxhash",
|
||||||
"quinn-proto",
|
"quinn-proto 0.8.4",
|
||||||
"quinn-udp",
|
"quinn-udp",
|
||||||
"rustls",
|
"rustls 0.20.4",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tracing",
|
"tracing",
|
||||||
"webpki",
|
"webpki 0.22.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quinn-proto"
|
||||||
|
version = "0.7.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "047aa96ec7ee6acabad7a1318dff72e9aff8994316bf2166c9b94cbec78ca54c"
|
||||||
|
dependencies = [
|
||||||
|
"bytes",
|
||||||
|
"ct-logs",
|
||||||
|
"rand",
|
||||||
|
"ring",
|
||||||
|
"rustls 0.19.1",
|
||||||
|
"rustls-native-certs 0.5.0",
|
||||||
|
"slab",
|
||||||
|
"thiserror",
|
||||||
|
"tinyvec",
|
||||||
|
"tracing",
|
||||||
|
"webpki 0.21.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1446,14 +1483,14 @@ dependencies = [
|
||||||
"fxhash",
|
"fxhash",
|
||||||
"rand",
|
"rand",
|
||||||
"ring",
|
"ring",
|
||||||
"rustls",
|
"rustls 0.20.4",
|
||||||
"rustls-native-certs",
|
"rustls-native-certs 0.6.2",
|
||||||
"rustls-pemfile 0.2.1",
|
"rustls-pemfile 0.2.1",
|
||||||
"slab",
|
"slab",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tinyvec",
|
"tinyvec",
|
||||||
"tracing",
|
"tracing",
|
||||||
"webpki",
|
"webpki 0.22.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1464,8 +1501,8 @@ checksum = "9f832d8958db3e84d2ec93b5eb2272b45aa23cf7f8fe6e79f578896f4e6c231b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"libc",
|
"libc",
|
||||||
"quinn-proto",
|
"quinn-proto 0.8.4",
|
||||||
"socket2",
|
"socket2 0.4.4",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tracing",
|
"tracing",
|
||||||
]
|
]
|
||||||
|
@ -1481,13 +1518,14 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand"
|
name = "rand"
|
||||||
version = "0.8.5"
|
version = "0.8.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"rand_chacha",
|
"rand_chacha",
|
||||||
"rand_core",
|
"rand_core",
|
||||||
|
"rand_hc",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1509,6 +1547,15 @@ dependencies = [
|
||||||
"getrandom",
|
"getrandom",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_hc"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7"
|
||||||
|
dependencies = [
|
||||||
|
"rand_core",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rcgen"
|
name = "rcgen"
|
||||||
version = "0.8.13"
|
version = "0.8.13"
|
||||||
|
@ -1590,7 +1637,7 @@ dependencies = [
|
||||||
"native-tls",
|
"native-tls",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"rustls",
|
"rustls 0.20.4",
|
||||||
"rustls-pemfile 0.3.0",
|
"rustls-pemfile 0.3.0",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
@ -1677,6 +1724,19 @@ dependencies = [
|
||||||
"walkdir",
|
"walkdir",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustls"
|
||||||
|
version = "0.19.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7"
|
||||||
|
dependencies = [
|
||||||
|
"base64",
|
||||||
|
"log",
|
||||||
|
"ring",
|
||||||
|
"sct 0.6.1",
|
||||||
|
"webpki 0.21.4",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls"
|
name = "rustls"
|
||||||
version = "0.20.4"
|
version = "0.20.4"
|
||||||
|
@ -1685,8 +1745,20 @@ checksum = "4fbfeb8d0ddb84706bc597a5574ab8912817c52a397f819e5b614e2265206921"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"ring",
|
"ring",
|
||||||
"sct",
|
"sct 0.7.0",
|
||||||
"webpki",
|
"webpki 0.22.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustls-native-certs"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5a07b7c1885bd8ed3831c289b7870b13ef46fe0e856d288c30d9cc17d75a2092"
|
||||||
|
dependencies = [
|
||||||
|
"openssl-probe",
|
||||||
|
"rustls 0.19.1",
|
||||||
|
"schannel",
|
||||||
|
"security-framework",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1771,6 +1843,16 @@ version = "1.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sct"
|
||||||
|
version = "0.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce"
|
||||||
|
dependencies = [
|
||||||
|
"ring",
|
||||||
|
"untrusted",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sct"
|
name = "sct"
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
|
@ -1902,6 +1984,17 @@ version = "1.7.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309"
|
checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "socket2"
|
||||||
|
version = "0.3.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "122e570113d28d773067fab24266b66753f6ea915758651696b6e35e49f88d6e"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "socket2"
|
name = "socket2"
|
||||||
version = "0.4.4"
|
version = "0.4.4"
|
||||||
|
@ -1984,18 +2077,18 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "1.0.37"
|
version = "1.0.29"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e"
|
checksum = "602eca064b2d83369e2b2f34b09c70b605402801927c65c11071ac911d299b88"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"thiserror-impl",
|
"thiserror-impl",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror-impl"
|
name = "thiserror-impl"
|
||||||
version = "1.0.37"
|
version = "1.0.29"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb"
|
checksum = "bad553cc2c78e8de258400763a647e80e6d1b31ee237275d756f6836d204494c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -2039,20 +2132,20 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "1.21.2"
|
version = "1.17.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a9e03c497dc955702ba729190dc4aac6f2a0ce97f913e5b1b5912fc5039d9099"
|
checksum = "2af73ac49756f3f7c01172e34a23e5d0216f6c32333757c2c61feb2bbff5a5ee"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
|
||||||
"bytes",
|
"bytes",
|
||||||
"libc",
|
"libc",
|
||||||
"memchr",
|
"memchr",
|
||||||
"mio",
|
"mio 0.8.2",
|
||||||
"num_cpus",
|
"num_cpus",
|
||||||
|
"once_cell",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"signal-hook-registry",
|
"signal-hook-registry",
|
||||||
"socket2",
|
"socket2 0.4.4",
|
||||||
"tokio-macros",
|
"tokio-macros",
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
@ -2084,9 +2177,9 @@ version = "0.23.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4151fda0cf2798550ad0b34bcfc9b9dcc2a9d2471c895c68f3a8818e54f2389e"
|
checksum = "4151fda0cf2798550ad0b34bcfc9b9dcc2a9d2471c895c68f3a8818e54f2389e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rustls",
|
"rustls 0.20.4",
|
||||||
"tokio",
|
"tokio",
|
||||||
"webpki",
|
"webpki 0.22.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2449,6 +2542,16 @@ dependencies = [
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "webpki"
|
||||||
|
version = "0.21.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea"
|
||||||
|
dependencies = [
|
||||||
|
"ring",
|
||||||
|
"untrusted",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "webpki"
|
name = "webpki"
|
||||||
version = "0.22.0"
|
version = "0.22.0"
|
||||||
|
@ -2465,7 +2568,7 @@ version = "0.22.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "44d8de8415c823c8abd270ad483c6feeac771fad964890779f9a8cb24fbbc1bf"
|
checksum = "44d8de8415c823c8abd270ad483c6feeac771fad964890779f9a8cb24fbbc1bf"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"webpki",
|
"webpki 0.22.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2505,24 +2608,11 @@ version = "0.34.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5acdd78cb4ba54c0045ac14f62d8f94a03d10047904ae2a40afa1e99d8f70825"
|
checksum = "5acdd78cb4ba54c0045ac14f62d8f94a03d10047904ae2a40afa1e99d8f70825"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows_aarch64_msvc 0.34.0",
|
"windows_aarch64_msvc",
|
||||||
"windows_i686_gnu 0.34.0",
|
"windows_i686_gnu",
|
||||||
"windows_i686_msvc 0.34.0",
|
"windows_i686_msvc",
|
||||||
"windows_x86_64_gnu 0.34.0",
|
"windows_x86_64_gnu",
|
||||||
"windows_x86_64_msvc 0.34.0",
|
"windows_x86_64_msvc",
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-sys"
|
|
||||||
version = "0.36.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2"
|
|
||||||
dependencies = [
|
|
||||||
"windows_aarch64_msvc 0.36.1",
|
|
||||||
"windows_i686_gnu 0.36.1",
|
|
||||||
"windows_i686_msvc 0.36.1",
|
|
||||||
"windows_x86_64_gnu 0.36.1",
|
|
||||||
"windows_x86_64_msvc 0.36.1",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2531,60 +2621,30 @@ version = "0.34.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "17cffbe740121affb56fad0fc0e421804adf0ae00891205213b5cecd30db881d"
|
checksum = "17cffbe740121affb56fad0fc0e421804adf0ae00891205213b5cecd30db881d"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_aarch64_msvc"
|
|
||||||
version = "0.36.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_gnu"
|
name = "windows_i686_gnu"
|
||||||
version = "0.34.0"
|
version = "0.34.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2564fde759adb79129d9b4f54be42b32c89970c18ebf93124ca8870a498688ed"
|
checksum = "2564fde759adb79129d9b4f54be42b32c89970c18ebf93124ca8870a498688ed"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_i686_gnu"
|
|
||||||
version = "0.36.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_msvc"
|
name = "windows_i686_msvc"
|
||||||
version = "0.34.0"
|
version = "0.34.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9cd9d32ba70453522332c14d38814bceeb747d80b3958676007acadd7e166956"
|
checksum = "9cd9d32ba70453522332c14d38814bceeb747d80b3958676007acadd7e166956"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_i686_msvc"
|
|
||||||
version = "0.36.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_gnu"
|
name = "windows_x86_64_gnu"
|
||||||
version = "0.34.0"
|
version = "0.34.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cfce6deae227ee8d356d19effc141a509cc503dfd1f850622ec4b0f84428e1f4"
|
checksum = "cfce6deae227ee8d356d19effc141a509cc503dfd1f850622ec4b0f84428e1f4"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_x86_64_gnu"
|
|
||||||
version = "0.36.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_msvc"
|
name = "windows_x86_64_msvc"
|
||||||
version = "0.34.0"
|
version = "0.34.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d19538ccc21819d01deaf88d6a17eae6596a12e9aafdbb97916fb49896d89de9"
|
checksum = "d19538ccc21819d01deaf88d6a17eae6596a12e9aafdbb97916fb49896d89de9"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_x86_64_msvc"
|
|
||||||
version = "0.36.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winreg"
|
name = "winreg"
|
||||||
version = "0.10.1"
|
version = "0.10.1"
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "insecure_chat"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
hyper = { version = "0.14.20", features = ["http1", "server", "tcp"] }
|
|
||||||
mac_address = "1.1.4"
|
|
||||||
nix = "0.25.0"
|
|
||||||
ptth_diceware = { path = "../ptth_diceware" }
|
|
||||||
thiserror = "1.0.37"
|
|
||||||
tokio = { version = "1.21.2", features = ["net", "rt-multi-thread", "fs"] }
|
|
|
@ -1,125 +0,0 @@
|
||||||
// IP address module
|
|
||||||
// Copied from the `lookaround` project
|
|
||||||
|
|
||||||
use std::{
|
|
||||||
net::Ipv4Addr,
|
|
||||||
process::Command,
|
|
||||||
str::FromStr,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive (Debug, thiserror::Error)]
|
|
||||||
pub enum Error {
|
|
||||||
#[error (transparent)]
|
|
||||||
Io (#[from] std::io::Error),
|
|
||||||
#[error (transparent)]
|
|
||||||
FromUtf8 (#[from] std::string::FromUtf8Error),
|
|
||||||
#[error ("Self-IP detection is not implemented on Mac OS")]
|
|
||||||
NotImplementedOnMac,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
pub fn get_ips () -> Result <Vec <Ipv4Addr>, Error> {
|
|
||||||
let output = linux::get_ip_addr_output ()?;
|
|
||||||
|
|
||||||
Ok (linux::parse_ip_addr_output (&output))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
|
||||||
pub fn get_ips () -> Result <Vec <Ipv4Addr>, Error> {
|
|
||||||
Err (Error::NotImplementedOnMac)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(target_os = "windows")]
|
|
||||||
pub fn get_ips () -> Result <Vec <Ipv4Addr>, Error> {
|
|
||||||
let output = windows::get_ip_config_output ()?;
|
|
||||||
|
|
||||||
Ok (windows::parse_ip_config_output (&output))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
pub mod linux {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
pub fn get_ip_addr_output () -> Result <String, Error> {
|
|
||||||
let output = Command::new ("ip")
|
|
||||||
.arg ("addr")
|
|
||||||
.output ()?;
|
|
||||||
let output = output.stdout.as_slice ();
|
|
||||||
let output = String::from_utf8 (output.to_vec ())?;
|
|
||||||
Ok (output)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn parse_ip_addr_output (output: &str) -> Vec <Ipv4Addr> {
|
|
||||||
// I wrote this in FP style because I was bored.
|
|
||||||
|
|
||||||
output.lines ()
|
|
||||||
.map (|l| l.trim_start ())
|
|
||||||
.filter_map (|l| l.strip_prefix ("inet "))
|
|
||||||
.filter_map (|l| l.find ('/').map (|x| &l [0..x]))
|
|
||||||
.filter_map (|l| Ipv4Addr::from_str (l).ok ())
|
|
||||||
.filter (|a| ! a.is_loopback ())
|
|
||||||
.collect ()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(target_os = "windows")]
|
|
||||||
pub mod windows {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
pub fn get_ip_config_output () -> Result <String, Error> {
|
|
||||||
let output = Command::new ("ipconfig")
|
|
||||||
.output ()?;
|
|
||||||
let output = output.stdout.as_slice ();
|
|
||||||
let output = String::from_utf8 (output.to_vec ())?;
|
|
||||||
Ok (output)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn parse_ip_config_output (output: &str) -> Vec <Ipv4Addr> {
|
|
||||||
let mut addrs = vec! [];
|
|
||||||
|
|
||||||
for line in output.lines () {
|
|
||||||
let line = line.trim_start ();
|
|
||||||
|
|
||||||
// Maybe only works on English locales?
|
|
||||||
if ! line.starts_with ("IPv4 Address") {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let colon_pos = match line.find (':') {
|
|
||||||
None => continue,
|
|
||||||
Some (x) => x,
|
|
||||||
};
|
|
||||||
let line = &line [colon_pos + 2..];
|
|
||||||
|
|
||||||
let addr = match Ipv4Addr::from_str (line) {
|
|
||||||
Err (_) => continue,
|
|
||||||
Ok (x) => x,
|
|
||||||
};
|
|
||||||
|
|
||||||
addrs.push (addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
addrs
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg (test)]
|
|
||||||
mod test {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test () {
|
|
||||||
for (input, expected) in [
|
|
||||||
(
|
|
||||||
r"
|
|
||||||
IPv4 Address . . .. . . . : 192.168.1.1
|
|
||||||
",
|
|
||||||
vec! [
|
|
||||||
Ipv4Addr::new (192, 168, 1, 1),
|
|
||||||
]
|
|
||||||
),
|
|
||||||
] {
|
|
||||||
let actual = parse_ip_config_output (input);
|
|
||||||
assert_eq! (actual, expected);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,299 +0,0 @@
|
||||||
use std::{
|
|
||||||
collections::*,
|
|
||||||
net::{
|
|
||||||
Ipv4Addr,
|
|
||||||
SocketAddrV4,
|
|
||||||
},
|
|
||||||
sync::Arc,
|
|
||||||
};
|
|
||||||
|
|
||||||
use hyper::{
|
|
||||||
Body,
|
|
||||||
Method,
|
|
||||||
Request,
|
|
||||||
Response,
|
|
||||||
Server,
|
|
||||||
StatusCode,
|
|
||||||
service::{
|
|
||||||
make_service_fn,
|
|
||||||
service_fn,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
use tokio::{
|
|
||||||
net::UdpSocket,
|
|
||||||
sync::RwLock,
|
|
||||||
};
|
|
||||||
|
|
||||||
mod ip;
|
|
||||||
|
|
||||||
fn main () -> Result <(), Error>
|
|
||||||
{
|
|
||||||
let mut args = std::env::args ();
|
|
||||||
let mut bail_unknown = true;
|
|
||||||
let mut last_unknown = None;
|
|
||||||
let mut name = ptth_diceware::passphrase ("_", 3);
|
|
||||||
let mut subcommand_count = 0;
|
|
||||||
let mut subcommand = None;
|
|
||||||
|
|
||||||
args.next ();
|
|
||||||
while let Some (arg) = args.next () {
|
|
||||||
if arg == "--ignore-unknown" {
|
|
||||||
bail_unknown = false;
|
|
||||||
}
|
|
||||||
if arg == "--name" {
|
|
||||||
name = args.next ().unwrap ().to_string ();
|
|
||||||
}
|
|
||||||
else if arg == "peer" {
|
|
||||||
subcommand = Some (Subcommand::Peer);
|
|
||||||
subcommand_count += 1;
|
|
||||||
}
|
|
||||||
else if arg == "receiver" {
|
|
||||||
subcommand = Some (Subcommand::Receiver);
|
|
||||||
subcommand_count += 1;
|
|
||||||
}
|
|
||||||
else if arg == "sender" {
|
|
||||||
subcommand = Some (Subcommand::Sender);
|
|
||||||
subcommand_count += 1;
|
|
||||||
}
|
|
||||||
else if arg == "spy" {
|
|
||||||
subcommand = Some (Subcommand::Spy);
|
|
||||||
subcommand_count += 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
last_unknown = Some (arg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if bail_unknown {
|
|
||||||
if let Some (last_unknown) = last_unknown {
|
|
||||||
eprintln! ("Unknown argument `{}`", last_unknown);
|
|
||||||
return Err (Error::Args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if subcommand_count >= 2 {
|
|
||||||
eprintln! ("Detected {} subcommands in arguments", subcommand_count);
|
|
||||||
return Err (Error::Args)
|
|
||||||
}
|
|
||||||
|
|
||||||
let rt = tokio::runtime::Runtime::new ()?;
|
|
||||||
|
|
||||||
let params = Params::default ();
|
|
||||||
|
|
||||||
rt.block_on (async {
|
|
||||||
if let Some (cmd) = subcommand {
|
|
||||||
return match cmd {
|
|
||||||
Subcommand::Peer => peer (params).await,
|
|
||||||
Subcommand::Receiver => receiver (params).await,
|
|
||||||
Subcommand::Sender => sender (params).await,
|
|
||||||
Subcommand::Spy => spy (params),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
println! ("Name is `{}`", name);
|
|
||||||
|
|
||||||
Ok::<_, Error> (())
|
|
||||||
})?;
|
|
||||||
|
|
||||||
Ok (())
|
|
||||||
}
|
|
||||||
|
|
||||||
enum Subcommand {
|
|
||||||
Peer,
|
|
||||||
Receiver,
|
|
||||||
Sender,
|
|
||||||
Spy,
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Params {
|
|
||||||
multicast_group: (Ipv4Addr, u16),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for Params {
|
|
||||||
fn default () -> Self {
|
|
||||||
let multicast_group = (Ipv4Addr::new (225, 100, 99, 98), 9041);
|
|
||||||
|
|
||||||
Self {
|
|
||||||
multicast_group,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn peer (params: Params) -> Result <(), Error>
|
|
||||||
{
|
|
||||||
let (multicast_addr, multicast_port) = params.multicast_group;
|
|
||||||
let socket = tokio::net::UdpSocket::bind (SocketAddrV4::new (Ipv4Addr::UNSPECIFIED, multicast_port)).await?;
|
|
||||||
|
|
||||||
socket.join_multicast_v4 (multicast_addr, Ipv4Addr::UNSPECIFIED)?;
|
|
||||||
eprintln! ("Multicast group is {:?}", params.multicast_group);
|
|
||||||
eprintln! ("Local addr is {}", socket.local_addr ()?);
|
|
||||||
|
|
||||||
let peer = Peer {
|
|
||||||
outbox: Outbox {
|
|
||||||
index: 1000,
|
|
||||||
messages: Default::default (),
|
|
||||||
}.into (),
|
|
||||||
params,
|
|
||||||
socket,
|
|
||||||
};
|
|
||||||
|
|
||||||
let state = Arc::new (peer);
|
|
||||||
|
|
||||||
let make_svc = make_service_fn (|_conn| {
|
|
||||||
let state = state.clone ();
|
|
||||||
|
|
||||||
async {
|
|
||||||
Ok::<_, String> (service_fn (move |req| {
|
|
||||||
let state = state.clone ();
|
|
||||||
peer_handle_all (req, state)
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let addr = std::net::SocketAddr::from (([127, 0, 0, 1], multicast_port));
|
|
||||||
let server = Server::bind (&addr)
|
|
||||||
.serve (make_svc);
|
|
||||||
|
|
||||||
eprintln! ("Local UI on {}", addr);
|
|
||||||
|
|
||||||
server.await?;
|
|
||||||
|
|
||||||
Ok (())
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Peer {
|
|
||||||
outbox: RwLock <Outbox>,
|
|
||||||
params: Params,
|
|
||||||
socket: UdpSocket,
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Outbox {
|
|
||||||
index: u32,
|
|
||||||
messages: VecDeque <SentMessage>,
|
|
||||||
}
|
|
||||||
|
|
||||||
struct SentMessage {
|
|
||||||
index: u32,
|
|
||||||
body: Vec <u8>,
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn peer_handle_all (req: Request <Body>, state: Arc <Peer>)
|
|
||||||
-> Result <Response <Body>, Error>
|
|
||||||
{
|
|
||||||
if req.method () == Method::POST {
|
|
||||||
if req.uri () == "/paste" {
|
|
||||||
let body = hyper::body::to_bytes (req.into_body ()).await?;
|
|
||||||
if body.len () > 1024 {
|
|
||||||
let resp = Response::builder ()
|
|
||||||
.status (StatusCode::BAD_REQUEST)
|
|
||||||
.body (Body::from ("Message body must be <= 1024 bytes"))?;
|
|
||||||
return Ok (resp);
|
|
||||||
}
|
|
||||||
let body = body.to_vec ();
|
|
||||||
|
|
||||||
let msg_index;
|
|
||||||
{
|
|
||||||
let mut outbox = state.outbox.write ().await;
|
|
||||||
let msg = SentMessage {
|
|
||||||
index: outbox.index,
|
|
||||||
body: body.clone (),
|
|
||||||
};
|
|
||||||
msg_index = msg.index;
|
|
||||||
outbox.messages.push_back (msg);
|
|
||||||
if outbox.messages.len () > 10 {
|
|
||||||
outbox.messages.pop_front ();
|
|
||||||
}
|
|
||||||
outbox.index += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
state.socket.send_to (&body, state.params.multicast_group).await?;
|
|
||||||
|
|
||||||
return Ok (Response::new (format! ("Pasted message {}\n", msg_index).into ()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok (Response::new (":V\n".into ()))
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn receiver (params: Params) -> Result <(), Error>
|
|
||||||
{
|
|
||||||
let (multicast_addr, multicast_port) = params.multicast_group;
|
|
||||||
let socket = tokio::net::UdpSocket::bind (SocketAddrV4::new (Ipv4Addr::UNSPECIFIED, multicast_port)).await?;
|
|
||||||
|
|
||||||
socket.join_multicast_v4 (multicast_addr, Ipv4Addr::UNSPECIFIED)?;
|
|
||||||
eprintln! ("Multicast group is {:?}", params.multicast_group);
|
|
||||||
eprintln! ("Local addr is {}", socket.local_addr ()?);
|
|
||||||
|
|
||||||
loop {
|
|
||||||
let mut buf = vec! [0u8; 2048];
|
|
||||||
|
|
||||||
let (bytes_recved, remote_addr) = socket.recv_from (&mut buf).await?;
|
|
||||||
buf.truncate (bytes_recved);
|
|
||||||
|
|
||||||
println! ("Received {} bytes from {}", bytes_recved, remote_addr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn sender (params: Params) -> Result <(), Error>
|
|
||||||
{
|
|
||||||
let (multicast_addr, multicast_port) = params.multicast_group;
|
|
||||||
let socket = tokio::net::UdpSocket::bind (SocketAddrV4::new (Ipv4Addr::UNSPECIFIED, 0)).await?;
|
|
||||||
|
|
||||||
socket.join_multicast_v4 (multicast_addr, Ipv4Addr::UNSPECIFIED)?;
|
|
||||||
eprintln! ("Multicast group is {:?}", params.multicast_group);
|
|
||||||
eprintln! ("Local addr is {}", socket.local_addr ()?);
|
|
||||||
|
|
||||||
socket.send_to (&[], params.multicast_group).await?;
|
|
||||||
|
|
||||||
Ok (())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn spy (params: Params) -> Result <(), Error>
|
|
||||||
{
|
|
||||||
let (multicast_addr, multicast_port) = params.multicast_group;
|
|
||||||
|
|
||||||
let socket = match std::net::UdpSocket::bind (SocketAddrV4::new (Ipv4Addr::UNSPECIFIED, multicast_port)) {
|
|
||||||
Ok (x) => x,
|
|
||||||
Err (e) => if e.kind () == std::io::ErrorKind::AddrInUse {
|
|
||||||
eprintln! ("Address in use. You can only run 1 instance of Insecure Chat at a time, even in spy mode.");
|
|
||||||
return Err (Error::AddrInUse);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return Err (e.into ());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
for bind_addr in ip::get_ips ()? {
|
|
||||||
socket.join_multicast_v4 (&multicast_addr, &bind_addr)?;
|
|
||||||
// eprintln! ("Joined multicast with {}", bind_addr);
|
|
||||||
}
|
|
||||||
eprintln! ("Multicast addr is {}", multicast_addr);
|
|
||||||
eprintln! ("Local addr is {}", socket.local_addr ()?);
|
|
||||||
|
|
||||||
loop {
|
|
||||||
let mut buf = vec! [0u8; 2048];
|
|
||||||
|
|
||||||
eprintln! ("Listening for UDP packets...");
|
|
||||||
let (bytes_recved, remote_addr) = socket.recv_from (&mut buf)?;
|
|
||||||
buf.truncate (bytes_recved);
|
|
||||||
|
|
||||||
println! ("Received {} bytes from {}", bytes_recved, remote_addr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive (Debug, thiserror::Error)]
|
|
||||||
enum Error {
|
|
||||||
#[error ("Address in use")]
|
|
||||||
AddrInUse,
|
|
||||||
#[error ("CLI args")]
|
|
||||||
Args,
|
|
||||||
#[error (transparent)]
|
|
||||||
Hyper (#[from] hyper::Error),
|
|
||||||
#[error (transparent)]
|
|
||||||
HyperHttp (#[from] hyper::http::Error),
|
|
||||||
#[error (transparent)]
|
|
||||||
Io (#[from] std::io::Error),
|
|
||||||
#[error (transparent)]
|
|
||||||
Ip (#[from] ip::Error),
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
[package]
|
|
||||||
description = "A diceware passphrase generator with 1,200 words, only depends on `rand`"
|
|
||||||
name = "ptth_diceware"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
rand = "0.8.5"
|
|
|
@ -1,44 +0,0 @@
|
||||||
use rand::Rng;
|
|
||||||
|
|
||||||
pub fn main () {
|
|
||||||
let passphrase = passphrase (" ", 8);
|
|
||||||
println! ("{}", passphrase);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn passphrase (separator: &str, len: usize) -> String {
|
|
||||||
let diceware = Diceware::default ();
|
|
||||||
|
|
||||||
let random_words: Vec <&str> = (0..len)
|
|
||||||
.map (|_| diceware.random_word ())
|
|
||||||
.collect ();
|
|
||||||
|
|
||||||
random_words.join (separator)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Diceware {
|
|
||||||
words: Vec <String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for Diceware {
|
|
||||||
fn default () -> Self
|
|
||||||
{
|
|
||||||
let wordlist = include_str! ("eff_short_wordlist_1.txt");
|
|
||||||
let words: Vec <_> = wordlist.split ('\n').take (1253).map (str::to_string).collect ();
|
|
||||||
|
|
||||||
assert_eq! (words.len (), 1253);
|
|
||||||
assert_eq! (words [0], "acid");
|
|
||||||
assert_eq! (words [600], "large");
|
|
||||||
assert_eq! (words [1252], "zoom");
|
|
||||||
|
|
||||||
Self {
|
|
||||||
words,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Diceware {
|
|
||||||
pub fn random_word (&self) -> &str
|
|
||||||
{
|
|
||||||
&self.words [rand::thread_rng ().gen_range (0..self.words.len ())]
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,3 +0,0 @@
|
||||||
pub fn main () {
|
|
||||||
ptth_diceware::main ()
|
|
||||||
}
|
|
|
@ -16,7 +16,6 @@ anyhow = "1.0.38"
|
||||||
ctrlc = "3.2.1"
|
ctrlc = "3.2.1"
|
||||||
futures-util = "0.3.9"
|
futures-util = "0.3.9"
|
||||||
hex = "0.4.3"
|
hex = "0.4.3"
|
||||||
ptth_diceware = { path = "../ptth_diceware" }
|
|
||||||
ptth_file_server = { path = "../ptth_file_server_bin" }
|
ptth_file_server = { path = "../ptth_file_server_bin" }
|
||||||
ptth_server = { path = "../ptth_server" }
|
ptth_server = { path = "../ptth_server" }
|
||||||
ptth_quic = { path = "../ptth_quic" }
|
ptth_quic = { path = "../ptth_quic" }
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
use rand::Rng;
|
||||||
|
|
||||||
|
pub fn main () {
|
||||||
|
let wordlist = include_str! ("eff_short_wordlist_1.txt");
|
||||||
|
let words: Vec <_> = wordlist.split ('\n').take (1253).collect ();
|
||||||
|
|
||||||
|
assert_eq! (words.len (), 1253);
|
||||||
|
assert_eq! (words [0], "acid");
|
||||||
|
assert_eq! (words [600], "large");
|
||||||
|
assert_eq! (words [1252], "zoom");
|
||||||
|
|
||||||
|
let mut rng = rand::thread_rng ();
|
||||||
|
|
||||||
|
let random_words: Vec <&str> = (0..8)
|
||||||
|
.map (|_| {
|
||||||
|
words [rng.gen_range (0..words.len ())]
|
||||||
|
})
|
||||||
|
.collect ();
|
||||||
|
|
||||||
|
let passphrase = random_words.join (" ");
|
||||||
|
|
||||||
|
println! ("{}", passphrase);
|
||||||
|
}
|
|
@ -5,6 +5,7 @@ use std::{
|
||||||
|
|
||||||
use tokio::sync::watch;
|
use tokio::sync::watch;
|
||||||
|
|
||||||
|
mod diceware;
|
||||||
mod download;
|
mod download;
|
||||||
mod ulid;
|
mod ulid;
|
||||||
|
|
||||||
|
@ -29,7 +30,7 @@ async fn main () -> anyhow::Result <()> {
|
||||||
let (subcommand, args) = parse_args (&args)?;
|
let (subcommand, args) = parse_args (&args)?;
|
||||||
match subcommand {
|
match subcommand {
|
||||||
Diceware => {
|
Diceware => {
|
||||||
ptth_diceware::main ();
|
diceware::main ();
|
||||||
Ok (())
|
Ok (())
|
||||||
},
|
},
|
||||||
Download => download::main (args).await,
|
Download => download::main (args).await,
|
||||||
|
|
|
@ -1,30 +1,521 @@
|
||||||
use tokio::sync::watch;
|
use hyper::{
|
||||||
|
Body,
|
||||||
|
Request,
|
||||||
|
Response,
|
||||||
|
Server,
|
||||||
|
service::{
|
||||||
|
make_service_fn,
|
||||||
|
service_fn,
|
||||||
|
},
|
||||||
|
StatusCode,
|
||||||
|
};
|
||||||
|
use structopt::StructOpt;
|
||||||
|
use tokio::{
|
||||||
|
net::UdpSocket,
|
||||||
|
sync::watch,
|
||||||
|
};
|
||||||
|
|
||||||
use ptth_quic::prelude::*;
|
use ptth_quic::prelude::*;
|
||||||
|
use protocol::PeerId;
|
||||||
|
|
||||||
|
#[derive (Debug, StructOpt)]
|
||||||
|
struct Opt {
|
||||||
|
#[structopt (long)]
|
||||||
|
listen_addr: Option <String>,
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main () -> anyhow::Result <()> {
|
async fn main () -> anyhow::Result <()> {
|
||||||
use structopt::StructOpt;
|
|
||||||
|
|
||||||
tracing_subscriber::fmt::init ();
|
tracing_subscriber::fmt::init ();
|
||||||
|
|
||||||
let opt = ptth_quic::executable_relay_server::Opt::from_args ();
|
let opt = Opt::from_args ();
|
||||||
|
|
||||||
let (running_tx, mut running_rx) = watch::channel (true);
|
let listen_addr = opt.listen_addr.unwrap_or_else (|| String::from ("0.0.0.0:30380")).parse ()?;
|
||||||
|
let (mut incoming, server_cert) = make_server_endpoint (listen_addr)?;
|
||||||
|
println! ("Base64 cert: {}", base64::encode (&server_cert));
|
||||||
|
|
||||||
ctrlc::set_handler (move || {
|
tokio::fs::create_dir_all ("ptth_quic_output").await?;
|
||||||
running_tx.send (false).expect ("Couldn't forward Ctrl+C signal");
|
tokio::fs::write ("ptth_quic_output/quic_server.crt", &server_cert).await?;
|
||||||
})?;
|
|
||||||
trace! ("Set Ctrl+C handler");
|
|
||||||
|
|
||||||
tokio::select! {
|
let relay_state = Arc::new (RelayState::default ());
|
||||||
val = ptth_quic::executable_relay_server::main (opt) => {
|
|
||||||
|
|
||||||
|
let make_svc = {
|
||||||
|
let relay_state = Arc::clone (&relay_state);
|
||||||
|
make_service_fn (move |_conn| {
|
||||||
|
let relay_state = Arc::clone (&relay_state);
|
||||||
|
|
||||||
|
async move {
|
||||||
|
Ok::<_, String> (service_fn (move |req| {
|
||||||
|
let relay_state = Arc::clone (&relay_state);
|
||||||
|
|
||||||
|
handle_http (req, relay_state)
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
let http_addr = SocketAddr::from (([0, 0, 0, 0], 4004));
|
||||||
|
let http_server = Server::bind (&http_addr);
|
||||||
|
|
||||||
|
let tcp_port = 30382;
|
||||||
|
let tcp_listener = TcpListener::bind (("127.0.0.1", tcp_port)).await?;
|
||||||
|
|
||||||
|
let (_running_tx, running_rx) = watch::channel (true);
|
||||||
|
|
||||||
|
let task_quic_server = {
|
||||||
|
let relay_state = Arc::clone (&relay_state);
|
||||||
|
tokio::spawn (async move {
|
||||||
|
while let Some (conn) = incoming.next ().await {
|
||||||
|
let relay_state = Arc::clone (&relay_state);
|
||||||
|
|
||||||
|
// Each new peer QUIC connection gets its own task
|
||||||
|
tokio::spawn (async move {
|
||||||
|
let active = relay_state.stats.quic.connect ();
|
||||||
|
debug! ("QUIC connections: {}", active);
|
||||||
|
|
||||||
|
match handle_quic_connection (Arc::clone (&relay_state), conn).await {
|
||||||
|
Ok (_) => (),
|
||||||
|
Err (e) => warn! ("handle_quic_connection `{:?}`", e),
|
||||||
|
}
|
||||||
|
|
||||||
|
let active = relay_state.stats.quic.disconnect ();
|
||||||
|
debug! ("QUIC connections: {}", active);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok::<_, anyhow::Error> (())
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
let task_direc_server = {
|
||||||
|
let relay_state = Arc::clone (&relay_state);
|
||||||
|
|
||||||
|
tokio::spawn (async move {
|
||||||
|
let sock = UdpSocket::bind("0.0.0.0:30379").await?;
|
||||||
|
let mut buf = [0; 2048];
|
||||||
|
loop {
|
||||||
|
let (len, addr) = sock.recv_from (&mut buf).await?;
|
||||||
|
debug! ("{:?} bytes received from {:?}", len, addr);
|
||||||
|
|
||||||
|
let packet = Vec::from_iter ((&buf [0..len]).into_iter ().map (|x| *x));
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut direc_cookies = relay_state.direc_cookies.lock ().await;
|
||||||
|
|
||||||
|
if let Some (direc_state) = direc_cookies.remove (&packet) {
|
||||||
|
debug! ("Got PTTH_DIREC cookie for {}", direc_state.p2_id);
|
||||||
|
direc_state.p2_addr.send (addr).ok ();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
debug! ("UDP packet didn't match any PTTH_DIREC cookie");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok::<_, anyhow::Error> (())
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
let task_http_server = tokio::spawn (async move {
|
||||||
|
http_server.serve (make_svc).await?;
|
||||||
|
Ok::<_, anyhow::Error> (())
|
||||||
|
});
|
||||||
|
|
||||||
|
let task_tcp_server = {
|
||||||
|
let relay_state = Arc::clone (&relay_state);
|
||||||
|
tokio::spawn (async move {
|
||||||
|
while *running_rx.borrow () {
|
||||||
|
let (tcp_socket, _) = tcp_listener.accept ().await?;
|
||||||
|
|
||||||
|
let relay_state = Arc::clone (&relay_state);
|
||||||
|
tokio::spawn (async move {
|
||||||
|
let (_client_recv, _client_send) = tcp_socket.into_split ();
|
||||||
|
|
||||||
|
debug! ("Accepted direct TCP connection P1 --> P3");
|
||||||
|
|
||||||
|
let p4_server_proxies = relay_state.p4_server_proxies.lock ().await;
|
||||||
|
let _p4 = match p4_server_proxies.get ("bogus_server") {
|
||||||
|
Some (x) => x,
|
||||||
|
None => bail! ("That server isn't connected"),
|
||||||
|
};
|
||||||
|
|
||||||
|
// unimplemented! ();
|
||||||
|
/*
|
||||||
|
p4.req_channel.send (RequestP2ToP4 {
|
||||||
|
client_send,
|
||||||
|
client_recv,
|
||||||
|
client_id: "bogus_client".to_string (),
|
||||||
|
}).await.map_err (|_| anyhow::anyhow! ("Can't send request to P4 server"))?;
|
||||||
|
*/
|
||||||
|
Ok (())
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok::<_, anyhow::Error> (())
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
debug! ("Serving HTTP on {:?}", http_addr);
|
||||||
|
|
||||||
|
task_quic_server.await??;
|
||||||
|
task_http_server.await??;
|
||||||
|
task_tcp_server.await??;
|
||||||
|
task_direc_server.await??;
|
||||||
|
|
||||||
|
Ok (())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn handle_http (_req: Request <Body>, relay_state: Arc <RelayState>)
|
||||||
|
-> anyhow::Result <Response <Body>>
|
||||||
|
{
|
||||||
|
let debug_string;
|
||||||
|
{
|
||||||
|
let p4_server_proxies = relay_state.p4_server_proxies.lock ().await;
|
||||||
|
|
||||||
|
debug_string = format! ("{:#?}\n", p4_server_proxies.keys ().collect::<Vec<_>> ());
|
||||||
|
}
|
||||||
|
|
||||||
|
let resp = Response::builder ()
|
||||||
|
.status (StatusCode::OK)
|
||||||
|
.header ("content-type", "text/plain")
|
||||||
|
.body (Body::from (debug_string))?;
|
||||||
|
|
||||||
|
Ok (resp)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive (Default)]
|
||||||
|
struct RelayState {
|
||||||
|
p4_server_proxies: Mutex <HashMap <PeerId, P4State>>,
|
||||||
|
direc_cookies: Mutex <HashMap <Vec <u8>, DirecState>>,
|
||||||
|
stats: Stats,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct DirecState {
|
||||||
|
start_time: Instant,
|
||||||
|
p2_id: PeerId,
|
||||||
|
p2_addr: tokio::sync::oneshot::Sender <SocketAddr>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive (Default)]
|
||||||
|
struct Stats {
|
||||||
|
quic: ConnectEvents,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive (Default)]
|
||||||
|
struct ConnectEvents {
|
||||||
|
connects: AtomicU64,
|
||||||
|
disconnects: AtomicU64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ConnectEvents {
|
||||||
|
fn connect (&self) -> u64 {
|
||||||
|
let connects = self.connects.fetch_add (1, Ordering::Relaxed) + 1;
|
||||||
|
let disconnects = self.disconnects.load (Ordering::Relaxed);
|
||||||
|
connects - disconnects
|
||||||
|
}
|
||||||
|
|
||||||
|
fn disconnect (&self) -> u64 {
|
||||||
|
let disconnects = self.disconnects.fetch_add (1, Ordering::Relaxed) + 1;
|
||||||
|
let connects = self.connects.load (Ordering::Relaxed);
|
||||||
|
connects - disconnects
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _active (&self) -> u64 {
|
||||||
|
let connects = self.connects.load (Ordering::Relaxed);
|
||||||
|
let disconnects = self.disconnects.load (Ordering::Relaxed);
|
||||||
|
connects - disconnects
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct P4State {
|
||||||
|
req_channel: mpsc::Sender <RequestP2ToP4>,
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RelayState {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
struct RequestP2ToP4 {
|
||||||
|
client_send: quinn::SendStream,
|
||||||
|
client_recv: quinn::RecvStream,
|
||||||
|
client_id: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct PtthNewConnection {
|
||||||
|
client_send: quinn::SendStream,
|
||||||
|
client_recv: quinn::RecvStream,
|
||||||
|
server_send: quinn::SendStream,
|
||||||
|
server_recv: quinn::RecvStream,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct PtthConnection {
|
||||||
|
uplink_task: JoinHandle <anyhow::Result <()>>,
|
||||||
|
downlink_task: JoinHandle <anyhow::Result <()>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PtthNewConnection {
|
||||||
|
fn build (self) -> PtthConnection {
|
||||||
|
let Self {
|
||||||
|
mut client_send,
|
||||||
|
mut client_recv,
|
||||||
|
mut server_send,
|
||||||
|
mut server_recv,
|
||||||
|
} = self;
|
||||||
|
|
||||||
|
let uplink_task = tokio::spawn (async move {
|
||||||
|
// Uplink - Client to end server
|
||||||
|
|
||||||
|
let mut buf = vec! [0u8; 65_536];
|
||||||
|
while let Some (bytes_read) = client_recv.read (&mut buf).await? {
|
||||||
|
if bytes_read == 0 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
let buf_slice = &buf [0..bytes_read];
|
||||||
|
trace! ("Uplink relaying {} bytes", bytes_read);
|
||||||
|
server_send.write_all (buf_slice).await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
trace! ("Uplink closed");
|
||||||
|
|
||||||
|
Ok::<_, anyhow::Error> (())
|
||||||
|
});
|
||||||
|
|
||||||
|
let downlink_task = tokio::spawn (async move {
|
||||||
|
// Downlink - End server to client
|
||||||
|
|
||||||
|
let mut buf = vec! [0u8; 65_536];
|
||||||
|
while let Some (bytes_read) = server_recv.read (&mut buf).await? {
|
||||||
|
let buf_slice = &buf [0..bytes_read];
|
||||||
|
trace! ("Downlink relaying {} bytes", bytes_read);
|
||||||
|
client_send.write_all (buf_slice).await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
trace! ("Downlink closed");
|
||||||
|
|
||||||
|
Ok::<_, anyhow::Error> (())
|
||||||
|
});
|
||||||
|
|
||||||
|
PtthConnection {
|
||||||
|
uplink_task,
|
||||||
|
downlink_task,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn handle_quic_connection (
|
||||||
|
relay_state: Arc <RelayState>,
|
||||||
|
conn: quinn::Connecting,
|
||||||
|
) -> anyhow::Result <()>
|
||||||
|
{
|
||||||
|
let mut conn = conn.await?;
|
||||||
|
|
||||||
|
// Everyone who connects must identify themselves with the first
|
||||||
|
// bi stream
|
||||||
|
// TODO: Timeout
|
||||||
|
|
||||||
|
let (mut send, mut recv) = conn.bi_streams.next ().await.ok_or_else (|| anyhow::anyhow! ("QUIC client didn't identify itself"))??;
|
||||||
|
|
||||||
|
let peer = protocol::p3_accept_peer (&mut recv).await?;
|
||||||
|
|
||||||
|
match peer {
|
||||||
|
protocol::P3Peer::P2ClientProxy (peer) => {
|
||||||
|
trace! ("Accepting connection from P2 client");
|
||||||
|
// TODO: Check authorization for P2 peers
|
||||||
|
|
||||||
|
protocol::p3_authorize_p2_peer (&mut send).await?;
|
||||||
|
handle_p2_connection (relay_state, conn, peer).await?;
|
||||||
},
|
},
|
||||||
val = running_rx.changed () => {
|
protocol::P3Peer::P4ServerProxy (peer) => {
|
||||||
|
trace! ("Accepting connection from P4 end server");
|
||||||
|
// TODO: Check authorization for P4 peers
|
||||||
|
|
||||||
|
protocol::p3_authorize_p4_peer (&mut send).await?;
|
||||||
|
handle_p4_connection (relay_state, conn, peer).await?;
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok::<_, anyhow::Error> (())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn handle_p2_connection (
|
||||||
|
relay_state: Arc <RelayState>,
|
||||||
|
conn: quinn::NewConnection,
|
||||||
|
peer: protocol::P2ClientProxy,
|
||||||
|
) -> anyhow::Result <()>
|
||||||
|
{
|
||||||
|
let client_id = peer.id;
|
||||||
|
|
||||||
|
let quinn::NewConnection {
|
||||||
|
mut bi_streams,
|
||||||
|
..
|
||||||
|
} = conn;
|
||||||
|
|
||||||
|
while let Some (bi_stream) = bi_streams.next ().await {
|
||||||
|
let (send, mut recv) = bi_stream?;
|
||||||
|
let relay_state = Arc::clone (&relay_state);
|
||||||
|
let client_id = client_id.clone ();
|
||||||
|
|
||||||
|
tokio::spawn (async move {
|
||||||
|
debug! ("Request started for P2");
|
||||||
|
|
||||||
|
match protocol::p3_accept_p2_stream (&mut recv).await? {
|
||||||
|
protocol::P2ToP3Stream::ConnectP2ToP4 {
|
||||||
|
server_id,
|
||||||
|
} => {
|
||||||
|
handle_request_p2_to_p4 (
|
||||||
|
relay_state,
|
||||||
|
client_id,
|
||||||
|
server_id,
|
||||||
|
send,
|
||||||
|
recv
|
||||||
|
).await?
|
||||||
|
},
|
||||||
|
protocol::P2ToP3Stream::DirecP2ToP4 {
|
||||||
|
server_id,
|
||||||
|
cookie,
|
||||||
|
} => {
|
||||||
|
handle_direc_p2_to_p4 (
|
||||||
|
relay_state,
|
||||||
|
client_id,
|
||||||
|
server_id,
|
||||||
|
cookie,
|
||||||
|
send,
|
||||||
|
recv
|
||||||
|
).await?
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
debug! ("Request ended for P2");
|
||||||
|
|
||||||
|
Ok::<_, anyhow::Error> (())
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
debug! ("P2 {} disconnected", client_id);
|
||||||
|
Ok (())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn handle_request_p2_to_p4 (
|
||||||
|
relay_state: Arc <RelayState>,
|
||||||
|
client_id: String,
|
||||||
|
server_id: PeerId,
|
||||||
|
mut client_send: quinn::SendStream,
|
||||||
|
client_recv: quinn::RecvStream,
|
||||||
|
) -> anyhow::Result <()>
|
||||||
|
{
|
||||||
|
trace! ("P2 {} wants to connect to P4 {}", client_id, server_id);
|
||||||
|
|
||||||
|
// TODO: Check authorization for P2 to connect to P4
|
||||||
|
|
||||||
|
protocol::p3_authorize_p2_to_p4_connection (&mut client_send).await?;
|
||||||
|
|
||||||
|
{
|
||||||
|
let p4_server_proxies = relay_state.p4_server_proxies.lock ().await;
|
||||||
|
match p4_server_proxies.get (&server_id) {
|
||||||
|
Some (p4_state) => {
|
||||||
|
p4_state.req_channel.send (RequestP2ToP4 {
|
||||||
|
client_send,
|
||||||
|
client_recv,
|
||||||
|
client_id,
|
||||||
|
}).await.map_err (|_| anyhow::anyhow! ("Can't send request to P4 server"))?;
|
||||||
|
},
|
||||||
|
None => warn! ("That server isn't connected"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok (())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn handle_direc_p2_to_p4 (
|
||||||
|
relay_state: Arc <RelayState>,
|
||||||
|
client_id: String,
|
||||||
|
server_id: PeerId,
|
||||||
|
cookie: Vec <u8>,
|
||||||
|
mut client_send: quinn::SendStream,
|
||||||
|
client_recv: quinn::RecvStream,
|
||||||
|
) -> anyhow::Result <()>
|
||||||
|
{
|
||||||
|
debug! ("P2 {} wants a P2P connection to P4 {}", client_id, server_id);
|
||||||
|
|
||||||
|
// TODO: Check authorization
|
||||||
|
|
||||||
|
protocol::p3_authorize_p2_to_p4_direc (&mut client_send).await?;
|
||||||
|
|
||||||
|
let (tx, rx) = tokio::sync::oneshot::channel ();
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut direc_cookies = relay_state.direc_cookies.lock ().await;
|
||||||
|
direc_cookies.insert (cookie, DirecState {
|
||||||
|
start_time: Instant::now (),
|
||||||
|
p2_id: client_id.clone (),
|
||||||
|
p2_addr: tx,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
debug! ("Waiting to learn P2's WAN address...");
|
||||||
|
|
||||||
|
let wan_addr = rx.await?;
|
||||||
|
|
||||||
|
debug! ("And that WAN address is {}", wan_addr);
|
||||||
|
|
||||||
|
Ok (())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn handle_p4_connection (
|
||||||
|
relay_state: Arc <RelayState>,
|
||||||
|
conn: quinn::NewConnection,
|
||||||
|
peer: protocol::P4ServerProxy,
|
||||||
|
) -> anyhow::Result <()>
|
||||||
|
{
|
||||||
|
let server_id = peer.id;
|
||||||
|
let quinn::NewConnection {
|
||||||
|
connection,
|
||||||
|
..
|
||||||
|
} = conn;
|
||||||
|
let (tx, mut rx) = mpsc::channel (2);
|
||||||
|
|
||||||
|
let p4_state = P4State {
|
||||||
|
req_channel: tx,
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut p4_server_proxies = relay_state.p4_server_proxies.lock ().await;
|
||||||
|
p4_server_proxies.insert (server_id.clone (), p4_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
while let Some (req) = rx.recv ().await {
|
||||||
|
let connection = connection.clone ();
|
||||||
|
let server_id = server_id.clone ();
|
||||||
|
|
||||||
|
tokio::spawn (async move {
|
||||||
|
let RequestP2ToP4 {
|
||||||
|
client_send,
|
||||||
|
client_recv,
|
||||||
|
client_id,
|
||||||
|
} = req;
|
||||||
|
|
||||||
|
debug! ("P4 {} got a request from P2 {}", server_id, client_id);
|
||||||
|
|
||||||
|
let (server_send, server_recv) = protocol::p3_connect_p2_to_p4 (&connection, &client_id).await?;
|
||||||
|
|
||||||
|
trace! ("Relaying bytes...");
|
||||||
|
|
||||||
|
let ptth_conn = PtthNewConnection {
|
||||||
|
client_send,
|
||||||
|
client_recv,
|
||||||
|
server_send,
|
||||||
|
server_recv,
|
||||||
|
}.build ();
|
||||||
|
|
||||||
|
ptth_conn.uplink_task.await??;
|
||||||
|
ptth_conn.downlink_task.await??;
|
||||||
|
|
||||||
|
debug! ("Request ended for P4");
|
||||||
|
Ok::<_, anyhow::Error> (())
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
debug! ("P4 {} disconnected", server_id);
|
||||||
Ok (())
|
Ok (())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,514 +0,0 @@
|
||||||
use hyper::{
|
|
||||||
Body,
|
|
||||||
Request,
|
|
||||||
Response,
|
|
||||||
Server,
|
|
||||||
service::{
|
|
||||||
make_service_fn,
|
|
||||||
service_fn,
|
|
||||||
},
|
|
||||||
StatusCode,
|
|
||||||
};
|
|
||||||
use structopt::StructOpt;
|
|
||||||
use tokio::{
|
|
||||||
net::UdpSocket,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::prelude::*;
|
|
||||||
use protocol::PeerId;
|
|
||||||
|
|
||||||
#[derive (Debug, StructOpt)]
|
|
||||||
pub struct Opt {
|
|
||||||
#[structopt (long)]
|
|
||||||
listen_addr: Option <String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn main (opt: Opt) -> anyhow::Result <()>
|
|
||||||
{
|
|
||||||
let listen_addr = opt.listen_addr.unwrap_or_else (|| String::from ("0.0.0.0:30380")).parse ()?;
|
|
||||||
let (mut incoming, server_cert) = make_server_endpoint (listen_addr)?;
|
|
||||||
println! ("Base64 cert: {}", base64::encode (&server_cert));
|
|
||||||
|
|
||||||
tokio::fs::create_dir_all ("ptth_quic_output").await?;
|
|
||||||
tokio::fs::write ("ptth_quic_output/quic_server.crt", &server_cert).await?;
|
|
||||||
|
|
||||||
let relay_state = Arc::new (RelayState::default ());
|
|
||||||
|
|
||||||
let make_svc = {
|
|
||||||
let relay_state = Arc::clone (&relay_state);
|
|
||||||
make_service_fn (move |_conn| {
|
|
||||||
let relay_state = Arc::clone (&relay_state);
|
|
||||||
|
|
||||||
async move {
|
|
||||||
Ok::<_, String> (service_fn (move |req| {
|
|
||||||
let relay_state = Arc::clone (&relay_state);
|
|
||||||
|
|
||||||
handle_http (req, relay_state)
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
let http_addr = SocketAddr::from (([0, 0, 0, 0], 4004));
|
|
||||||
let http_server = Server::bind (&http_addr);
|
|
||||||
|
|
||||||
let tcp_port = 30382;
|
|
||||||
let tcp_listener = TcpListener::bind (("127.0.0.1", tcp_port)).await?;
|
|
||||||
|
|
||||||
let task_quic_server = {
|
|
||||||
let relay_state = Arc::clone (&relay_state);
|
|
||||||
tokio::spawn (async move {
|
|
||||||
while let Some (conn) = incoming.next ().await {
|
|
||||||
let relay_state = Arc::clone (&relay_state);
|
|
||||||
|
|
||||||
// Each new peer QUIC connection gets its own task
|
|
||||||
tokio::spawn (async move {
|
|
||||||
let active = relay_state.stats.quic.connect ();
|
|
||||||
debug! ("QUIC connections: {}", active);
|
|
||||||
|
|
||||||
match handle_quic_connection (Arc::clone (&relay_state), conn).await {
|
|
||||||
Ok (_) => (),
|
|
||||||
Err (e) => warn! ("handle_quic_connection `{:?}`", e),
|
|
||||||
}
|
|
||||||
|
|
||||||
let active = relay_state.stats.quic.disconnect ();
|
|
||||||
debug! ("QUIC connections: {}", active);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok::<_, anyhow::Error> (())
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
let task_direc_server = {
|
|
||||||
let relay_state = Arc::clone (&relay_state);
|
|
||||||
|
|
||||||
tokio::spawn (async move {
|
|
||||||
let sock = UdpSocket::bind("0.0.0.0:30379").await?;
|
|
||||||
let mut buf = [0; 2048];
|
|
||||||
loop {
|
|
||||||
let (len, addr) = sock.recv_from (&mut buf).await?;
|
|
||||||
debug! ("{:?} bytes received from {:?}", len, addr);
|
|
||||||
|
|
||||||
let packet = Vec::from_iter ((&buf [0..len]).into_iter ().map (|x| *x));
|
|
||||||
|
|
||||||
{
|
|
||||||
let mut direc_cookies = relay_state.direc_cookies.lock ().await;
|
|
||||||
|
|
||||||
if let Some (direc_state) = direc_cookies.remove (&packet) {
|
|
||||||
debug! ("Got PTTH_DIREC cookie for {}", direc_state.p2_id);
|
|
||||||
direc_state.p2_addr.send (addr).ok ();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
debug! ("UDP packet didn't match any PTTH_DIREC cookie");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok::<_, anyhow::Error> (())
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
let task_http_server = tokio::spawn (async move {
|
|
||||||
http_server.serve (make_svc).await?;
|
|
||||||
Ok::<_, anyhow::Error> (())
|
|
||||||
});
|
|
||||||
|
|
||||||
let task_tcp_server = {
|
|
||||||
let relay_state = Arc::clone (&relay_state);
|
|
||||||
tokio::spawn (async move {
|
|
||||||
loop {
|
|
||||||
let (tcp_socket, _) = tcp_listener.accept ().await?;
|
|
||||||
|
|
||||||
let relay_state = Arc::clone (&relay_state);
|
|
||||||
tokio::spawn (async move {
|
|
||||||
let (_client_recv, _client_send) = tcp_socket.into_split ();
|
|
||||||
|
|
||||||
debug! ("Accepted direct TCP connection P1 --> P3");
|
|
||||||
|
|
||||||
let p4_server_proxies = relay_state.p4_server_proxies.lock ().await;
|
|
||||||
let _p4 = match p4_server_proxies.get ("bogus_server") {
|
|
||||||
Some (x) => x,
|
|
||||||
None => bail! ("That server isn't connected"),
|
|
||||||
};
|
|
||||||
|
|
||||||
// unimplemented! ();
|
|
||||||
/*
|
|
||||||
p4.req_channel.send (RequestP2ToP4 {
|
|
||||||
client_send,
|
|
||||||
client_recv,
|
|
||||||
client_id: "bogus_client".to_string (),
|
|
||||||
}).await.map_err (|_| anyhow::anyhow! ("Can't send request to P4 server"))?;
|
|
||||||
*/
|
|
||||||
Ok (())
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok::<_, anyhow::Error> (())
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
debug! ("Serving HTTP on {:?}", http_addr);
|
|
||||||
|
|
||||||
task_quic_server.await??;
|
|
||||||
task_http_server.await??;
|
|
||||||
task_tcp_server.await??;
|
|
||||||
task_direc_server.await??;
|
|
||||||
|
|
||||||
Ok (())
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn handle_http (_req: Request <Body>, relay_state: Arc <RelayState>)
|
|
||||||
-> anyhow::Result <Response <Body>>
|
|
||||||
{
|
|
||||||
let debug_string;
|
|
||||||
{
|
|
||||||
let p4_server_proxies = relay_state.p4_server_proxies.lock ().await;
|
|
||||||
|
|
||||||
debug_string = format! ("{:#?}\n", p4_server_proxies.keys ().collect::<Vec<_>> ());
|
|
||||||
}
|
|
||||||
|
|
||||||
let resp = Response::builder ()
|
|
||||||
.status (StatusCode::OK)
|
|
||||||
.header ("content-type", "text/plain")
|
|
||||||
.body (Body::from (debug_string))?;
|
|
||||||
|
|
||||||
Ok (resp)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive (Default)]
|
|
||||||
struct RelayState {
|
|
||||||
p4_server_proxies: Mutex <HashMap <PeerId, P4State>>,
|
|
||||||
direc_cookies: Mutex <HashMap <Vec <u8>, DirecState>>,
|
|
||||||
stats: Stats,
|
|
||||||
}
|
|
||||||
|
|
||||||
struct DirecState {
|
|
||||||
start_time: Instant,
|
|
||||||
p2_id: PeerId,
|
|
||||||
p2_addr: tokio::sync::oneshot::Sender <SocketAddr>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive (Default)]
|
|
||||||
struct Stats {
|
|
||||||
quic: ConnectEvents,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive (Default)]
|
|
||||||
struct ConnectEvents {
|
|
||||||
connects: AtomicU64,
|
|
||||||
disconnects: AtomicU64,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ConnectEvents {
|
|
||||||
fn connect (&self) -> u64 {
|
|
||||||
let connects = self.connects.fetch_add (1, Ordering::Relaxed) + 1;
|
|
||||||
let disconnects = self.disconnects.load (Ordering::Relaxed);
|
|
||||||
connects - disconnects
|
|
||||||
}
|
|
||||||
|
|
||||||
fn disconnect (&self) -> u64 {
|
|
||||||
let disconnects = self.disconnects.fetch_add (1, Ordering::Relaxed) + 1;
|
|
||||||
let connects = self.connects.load (Ordering::Relaxed);
|
|
||||||
connects - disconnects
|
|
||||||
}
|
|
||||||
|
|
||||||
fn _active (&self) -> u64 {
|
|
||||||
let connects = self.connects.load (Ordering::Relaxed);
|
|
||||||
let disconnects = self.disconnects.load (Ordering::Relaxed);
|
|
||||||
connects - disconnects
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct P4State {
|
|
||||||
req_channel: mpsc::Sender <RequestP2ToP4>,
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
impl RelayState {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
struct RequestP2ToP4 {
|
|
||||||
client_send: quinn::SendStream,
|
|
||||||
client_recv: quinn::RecvStream,
|
|
||||||
client_id: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
struct PtthNewConnection {
|
|
||||||
client_send: quinn::SendStream,
|
|
||||||
client_recv: quinn::RecvStream,
|
|
||||||
server_send: quinn::SendStream,
|
|
||||||
server_recv: quinn::RecvStream,
|
|
||||||
}
|
|
||||||
|
|
||||||
struct PtthConnection {
|
|
||||||
uplink_task: JoinHandle <anyhow::Result <()>>,
|
|
||||||
downlink_task: JoinHandle <anyhow::Result <()>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PtthNewConnection {
|
|
||||||
fn build (self) -> PtthConnection {
|
|
||||||
let Self {
|
|
||||||
mut client_send,
|
|
||||||
mut client_recv,
|
|
||||||
mut server_send,
|
|
||||||
mut server_recv,
|
|
||||||
} = self;
|
|
||||||
|
|
||||||
let uplink_task = tokio::spawn (async move {
|
|
||||||
// Uplink - Client to end server
|
|
||||||
|
|
||||||
let mut buf = vec! [0u8; 65_536];
|
|
||||||
while let Some (bytes_read) = client_recv.read (&mut buf).await? {
|
|
||||||
if bytes_read == 0 {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
let buf_slice = &buf [0..bytes_read];
|
|
||||||
trace! ("Uplink relaying {} bytes", bytes_read);
|
|
||||||
server_send.write_all (buf_slice).await?;
|
|
||||||
}
|
|
||||||
|
|
||||||
trace! ("Uplink closed");
|
|
||||||
|
|
||||||
Ok::<_, anyhow::Error> (())
|
|
||||||
});
|
|
||||||
|
|
||||||
let downlink_task = tokio::spawn (async move {
|
|
||||||
// Downlink - End server to client
|
|
||||||
|
|
||||||
let mut buf = vec! [0u8; 65_536];
|
|
||||||
while let Some (bytes_read) = server_recv.read (&mut buf).await? {
|
|
||||||
let buf_slice = &buf [0..bytes_read];
|
|
||||||
trace! ("Downlink relaying {} bytes", bytes_read);
|
|
||||||
client_send.write_all (buf_slice).await?;
|
|
||||||
}
|
|
||||||
|
|
||||||
trace! ("Downlink closed");
|
|
||||||
|
|
||||||
Ok::<_, anyhow::Error> (())
|
|
||||||
});
|
|
||||||
|
|
||||||
PtthConnection {
|
|
||||||
uplink_task,
|
|
||||||
downlink_task,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn handle_quic_connection (
|
|
||||||
relay_state: Arc <RelayState>,
|
|
||||||
conn: quinn::Connecting,
|
|
||||||
) -> anyhow::Result <()>
|
|
||||||
{
|
|
||||||
let mut conn = conn.await?;
|
|
||||||
|
|
||||||
// Everyone who connects must identify themselves with the first
|
|
||||||
// bi stream
|
|
||||||
// TODO: Timeout
|
|
||||||
|
|
||||||
let (mut send, mut recv) = conn.bi_streams.next ().await.ok_or_else (|| anyhow::anyhow! ("QUIC client didn't identify itself"))??;
|
|
||||||
|
|
||||||
let peer = protocol::p3_accept_peer (&mut recv).await?;
|
|
||||||
|
|
||||||
match peer {
|
|
||||||
protocol::P3Peer::P2ClientProxy (peer) => {
|
|
||||||
trace! ("Accepting connection from P2 client");
|
|
||||||
// TODO: Check authorization for P2 peers
|
|
||||||
|
|
||||||
protocol::p3_authorize_p2_peer (&mut send).await?;
|
|
||||||
handle_p2_connection (relay_state, conn, peer).await?;
|
|
||||||
},
|
|
||||||
protocol::P3Peer::P4ServerProxy (peer) => {
|
|
||||||
trace! ("Accepting connection from P4 end server");
|
|
||||||
// TODO: Check authorization for P4 peers
|
|
||||||
|
|
||||||
protocol::p3_authorize_p4_peer (&mut send).await?;
|
|
||||||
handle_p4_connection (relay_state, conn, peer).await?;
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok::<_, anyhow::Error> (())
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn handle_p2_connection (
|
|
||||||
relay_state: Arc <RelayState>,
|
|
||||||
conn: quinn::NewConnection,
|
|
||||||
peer: protocol::P2ClientProxy,
|
|
||||||
) -> anyhow::Result <()>
|
|
||||||
{
|
|
||||||
let client_id = peer.id;
|
|
||||||
|
|
||||||
let quinn::NewConnection {
|
|
||||||
mut bi_streams,
|
|
||||||
..
|
|
||||||
} = conn;
|
|
||||||
|
|
||||||
while let Some (bi_stream) = bi_streams.next ().await {
|
|
||||||
let (send, mut recv) = bi_stream?;
|
|
||||||
let relay_state = Arc::clone (&relay_state);
|
|
||||||
let client_id = client_id.clone ();
|
|
||||||
|
|
||||||
tokio::spawn (async move {
|
|
||||||
debug! ("Request started for P2");
|
|
||||||
|
|
||||||
match protocol::p3_accept_p2_stream (&mut recv).await? {
|
|
||||||
protocol::P2ToP3Stream::ConnectP2ToP4 {
|
|
||||||
server_id,
|
|
||||||
} => {
|
|
||||||
handle_request_p2_to_p4 (
|
|
||||||
relay_state,
|
|
||||||
client_id,
|
|
||||||
server_id,
|
|
||||||
send,
|
|
||||||
recv
|
|
||||||
).await?
|
|
||||||
},
|
|
||||||
protocol::P2ToP3Stream::DirecP2ToP4 {
|
|
||||||
server_id,
|
|
||||||
cookie,
|
|
||||||
} => {
|
|
||||||
handle_direc_p2_to_p4 (
|
|
||||||
relay_state,
|
|
||||||
client_id,
|
|
||||||
server_id,
|
|
||||||
cookie,
|
|
||||||
send,
|
|
||||||
recv
|
|
||||||
).await?
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
debug! ("Request ended for P2");
|
|
||||||
|
|
||||||
Ok::<_, anyhow::Error> (())
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
debug! ("P2 {} disconnected", client_id);
|
|
||||||
Ok (())
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn handle_request_p2_to_p4 (
|
|
||||||
relay_state: Arc <RelayState>,
|
|
||||||
client_id: String,
|
|
||||||
server_id: PeerId,
|
|
||||||
mut client_send: quinn::SendStream,
|
|
||||||
client_recv: quinn::RecvStream,
|
|
||||||
) -> anyhow::Result <()>
|
|
||||||
{
|
|
||||||
trace! ("P2 {} wants to connect to P4 {}", client_id, server_id);
|
|
||||||
|
|
||||||
// TODO: Check authorization for P2 to connect to P4
|
|
||||||
|
|
||||||
protocol::p3_authorize_p2_to_p4_connection (&mut client_send).await?;
|
|
||||||
|
|
||||||
{
|
|
||||||
let p4_server_proxies = relay_state.p4_server_proxies.lock ().await;
|
|
||||||
match p4_server_proxies.get (&server_id) {
|
|
||||||
Some (p4_state) => {
|
|
||||||
p4_state.req_channel.send (RequestP2ToP4 {
|
|
||||||
client_send,
|
|
||||||
client_recv,
|
|
||||||
client_id,
|
|
||||||
}).await.map_err (|_| anyhow::anyhow! ("Can't send request to P4 server"))?;
|
|
||||||
},
|
|
||||||
None => warn! ("That server isn't connected"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok (())
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn handle_direc_p2_to_p4 (
|
|
||||||
relay_state: Arc <RelayState>,
|
|
||||||
client_id: String,
|
|
||||||
server_id: PeerId,
|
|
||||||
cookie: Vec <u8>,
|
|
||||||
mut client_send: quinn::SendStream,
|
|
||||||
client_recv: quinn::RecvStream,
|
|
||||||
) -> anyhow::Result <()>
|
|
||||||
{
|
|
||||||
debug! ("P2 {} wants a P2P connection to P4 {}", client_id, server_id);
|
|
||||||
|
|
||||||
// TODO: Check authorization
|
|
||||||
|
|
||||||
protocol::p3_authorize_p2_to_p4_direc (&mut client_send).await?;
|
|
||||||
|
|
||||||
let (tx, rx) = tokio::sync::oneshot::channel ();
|
|
||||||
|
|
||||||
{
|
|
||||||
let mut direc_cookies = relay_state.direc_cookies.lock ().await;
|
|
||||||
direc_cookies.insert (cookie, DirecState {
|
|
||||||
start_time: Instant::now (),
|
|
||||||
p2_id: client_id.clone (),
|
|
||||||
p2_addr: tx,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
debug! ("Waiting to learn P2's WAN address...");
|
|
||||||
|
|
||||||
let wan_addr = rx.await?;
|
|
||||||
|
|
||||||
debug! ("And that WAN address is {}", wan_addr);
|
|
||||||
|
|
||||||
Ok (())
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn handle_p4_connection (
|
|
||||||
relay_state: Arc <RelayState>,
|
|
||||||
conn: quinn::NewConnection,
|
|
||||||
peer: protocol::P4ServerProxy,
|
|
||||||
) -> anyhow::Result <()>
|
|
||||||
{
|
|
||||||
let server_id = peer.id;
|
|
||||||
let quinn::NewConnection {
|
|
||||||
connection,
|
|
||||||
..
|
|
||||||
} = conn;
|
|
||||||
let (tx, mut rx) = mpsc::channel (2);
|
|
||||||
|
|
||||||
let p4_state = P4State {
|
|
||||||
req_channel: tx,
|
|
||||||
};
|
|
||||||
|
|
||||||
{
|
|
||||||
let mut p4_server_proxies = relay_state.p4_server_proxies.lock ().await;
|
|
||||||
p4_server_proxies.insert (server_id.clone (), p4_state);
|
|
||||||
}
|
|
||||||
|
|
||||||
while let Some (req) = rx.recv ().await {
|
|
||||||
let connection = connection.clone ();
|
|
||||||
let server_id = server_id.clone ();
|
|
||||||
|
|
||||||
tokio::spawn (async move {
|
|
||||||
let RequestP2ToP4 {
|
|
||||||
client_send,
|
|
||||||
client_recv,
|
|
||||||
client_id,
|
|
||||||
} = req;
|
|
||||||
|
|
||||||
debug! ("P4 {} got a request from P2 {}", server_id, client_id);
|
|
||||||
|
|
||||||
let (server_send, server_recv) = protocol::p3_connect_p2_to_p4 (&connection, &client_id).await?;
|
|
||||||
|
|
||||||
trace! ("Relaying bytes...");
|
|
||||||
|
|
||||||
let ptth_conn = PtthNewConnection {
|
|
||||||
client_send,
|
|
||||||
client_recv,
|
|
||||||
server_send,
|
|
||||||
server_recv,
|
|
||||||
}.build ();
|
|
||||||
|
|
||||||
ptth_conn.uplink_task.await??;
|
|
||||||
ptth_conn.downlink_task.await??;
|
|
||||||
|
|
||||||
debug! ("Request ended for P4");
|
|
||||||
Ok::<_, anyhow::Error> (())
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
debug! ("P4 {} disconnected", server_id);
|
|
||||||
Ok (())
|
|
||||||
}
|
|
|
@ -1,7 +1,6 @@
|
||||||
pub mod client_proxy;
|
pub mod client_proxy;
|
||||||
pub mod connection;
|
pub mod connection;
|
||||||
pub mod executable_end_server;
|
pub mod executable_end_server;
|
||||||
pub mod executable_relay_server;
|
|
||||||
pub mod prelude;
|
pub mod prelude;
|
||||||
pub mod protocol;
|
pub mod protocol;
|
||||||
pub mod quinn_utils;
|
pub mod quinn_utils;
|
||||||
|
|
|
@ -12,7 +12,7 @@ anyhow = "1.0.38"
|
||||||
blake3 = "1.0.0"
|
blake3 = "1.0.0"
|
||||||
fltk = "1.2.8"
|
fltk = "1.2.8"
|
||||||
ptth_quic = { path = "../ptth_quic" }
|
ptth_quic = { path = "../ptth_quic" }
|
||||||
quinn = "0.8.5"
|
quinn = "0.7.2"
|
||||||
rand = "0.8.4"
|
rand = "0.8.4"
|
||||||
rand_chacha = "0.3.1"
|
rand_chacha = "0.3.1"
|
||||||
reqwest = "0.11.4"
|
reqwest = "0.11.4"
|
||||||
|
|
|
@ -238,7 +238,7 @@ fn main () -> anyhow::Result <()> {
|
||||||
let quinn::NewConnection {
|
let quinn::NewConnection {
|
||||||
connection,
|
connection,
|
||||||
..
|
..
|
||||||
} = protocol::p2_connect_to_p3 (&endpoint, relay_addr, &client_id).await
|
} = protocol::p2_connect_to_p3 (&endpoint, &relay_addr, &client_id).await
|
||||||
.context ("P2 can't connect to P3")?;
|
.context ("P2 can't connect to P3")?;
|
||||||
|
|
||||||
Ok::<_, anyhow::Error> (connection)
|
Ok::<_, anyhow::Error> (connection)
|
||||||
|
|
Loading…
Reference in New Issue