Compare commits
7 Commits
885b9c7892
...
7b4eeea12c
Author | SHA1 | Date |
---|---|---|
_ | 7b4eeea12c | |
_ | 2de0c5d6a7 | |
_ | 57d6086ea7 | |
_ | 5d560b91de | |
_ | 9d0bf4c0ba | |
_ | 1139ba4657 | |
_ | be03300f55 |
|
@ -81,9 +81,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.0.1"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
|
@ -266,22 +266,13 @@ dependencies = [
|
|||
"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]]
|
||||
name = "ctrlc"
|
||||
version = "3.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a19c6cedffdc8c03a3346d723eb20bd85a13362bb96dc2ac000842c6381ec7bf"
|
||||
dependencies = [
|
||||
"nix",
|
||||
"nix 0.23.1",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
|
@ -645,9 +636,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "httparse"
|
||||
version = "1.5.1"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "acd94fdbe1d4ff688b67b04eee2e17bd50995534a61539e45adfefb45e5e5503"
|
||||
checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904"
|
||||
|
||||
[[package]]
|
||||
name = "httpdate"
|
||||
|
@ -657,9 +648,9 @@ checksum = "6456b8a6c8f33fee7d958fcd1b60d55b11940a79e63ae87013e6d22e26034440"
|
|||
|
||||
[[package]]
|
||||
name = "hyper"
|
||||
version = "0.14.13"
|
||||
version = "0.14.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "15d1cfb9e4f68655fa04c01f59edb405b6074a0f7118ea881e5026e4a1cd8593"
|
||||
checksum = "02c929dc5c39e335a03c405292728118860721b10190d98c2a0f0efd5baafbac"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-channel",
|
||||
|
@ -670,9 +661,9 @@ dependencies = [
|
|||
"http-body",
|
||||
"httparse",
|
||||
"httpdate",
|
||||
"itoa 0.4.8",
|
||||
"itoa 1.0.1",
|
||||
"pin-project-lite",
|
||||
"socket2 0.4.4",
|
||||
"socket2",
|
||||
"tokio",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
|
@ -687,7 +678,7 @@ checksum = "d87c48c02e0dc5e3b849a2041db3029fd066650f8f717c07bf8ed78ccb895cac"
|
|||
dependencies = [
|
||||
"http",
|
||||
"hyper",
|
||||
"rustls 0.20.4",
|
||||
"rustls",
|
||||
"tokio",
|
||||
"tokio-rustls",
|
||||
]
|
||||
|
@ -726,6 +717,18 @@ dependencies = [
|
|||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "insecure_chat"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"hyper",
|
||||
"mac_address",
|
||||
"nix 0.25.0",
|
||||
"ptth_diceware",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ipnet"
|
||||
version = "2.3.1"
|
||||
|
@ -770,9 +773,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.122"
|
||||
version = "0.2.135"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec647867e2bf0772e28c8bcde4f0d19a9216916e890543b5a03ed8ef27b8f259"
|
||||
checksum = "68783febc7782c6c5cb401fbda4de5a9898be1762314da0bb2c10ced61f18b0c"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
|
@ -792,6 +795,16 @@ dependencies = [
|
|||
"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]]
|
||||
name = "maplit"
|
||||
version = "1.0.2"
|
||||
|
@ -844,38 +857,14 @@ checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
|
|||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.7.13"
|
||||
version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8c2bdb6314ec10835cd3293dd268473a835c02b7b352e788be788b3c6ca6bb16"
|
||||
checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"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",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miow"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
"windows-sys 0.36.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -898,9 +887,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.23.0"
|
||||
version = "0.23.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f305c2c2e4c39a82f7bf0bf65fb557f9070ce06781d4f2454295cc34b1c43188"
|
||||
checksum = "9f866317acbd3a240710c63f065ffb1e4fd466259045ccb504130b7f668f35c6"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cc",
|
||||
|
@ -910,12 +899,17 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "ntapi"
|
||||
version = "0.3.6"
|
||||
name = "nix"
|
||||
version = "0.25.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44"
|
||||
checksum = "e322c04a9e3440c327fca7b6c8a63e6890a32fa2ad689db972425f07e0d22abb"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
"autocfg",
|
||||
"bitflags",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"memoffset",
|
||||
"pin-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1018,7 +1012,7 @@ dependencies = [
|
|||
"libc",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"windows-sys",
|
||||
"windows-sys 0.34.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1210,6 +1204,13 @@ dependencies = [
|
|||
"tracing-futures",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ptth_diceware"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ptth_file_server"
|
||||
version = "1.1.0"
|
||||
|
@ -1249,6 +1250,7 @@ dependencies = [
|
|||
"ctrlc",
|
||||
"futures-util",
|
||||
"hex",
|
||||
"ptth_diceware",
|
||||
"ptth_file_server",
|
||||
"ptth_quic",
|
||||
"ptth_server",
|
||||
|
@ -1270,12 +1272,12 @@ dependencies = [
|
|||
"ctrlc",
|
||||
"futures-util",
|
||||
"hyper",
|
||||
"quinn 0.8.5",
|
||||
"quinn",
|
||||
"rand",
|
||||
"rcgen",
|
||||
"reqwest",
|
||||
"rmp-serde",
|
||||
"rustls 0.20.4",
|
||||
"rustls",
|
||||
"structopt",
|
||||
"tokio",
|
||||
"tracing",
|
||||
|
@ -1290,7 +1292,7 @@ dependencies = [
|
|||
"blake3",
|
||||
"fltk",
|
||||
"ptth_quic",
|
||||
"quinn 0.7.2",
|
||||
"quinn",
|
||||
"rand",
|
||||
"rand_chacha",
|
||||
"reqwest",
|
||||
|
@ -1415,26 +1417,6 @@ version = "2.0.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "quinn"
|
||||
version = "0.8.5"
|
||||
|
@ -1445,32 +1427,13 @@ dependencies = [
|
|||
"futures-channel",
|
||||
"futures-util",
|
||||
"fxhash",
|
||||
"quinn-proto 0.8.4",
|
||||
"quinn-proto",
|
||||
"quinn-udp",
|
||||
"rustls 0.20.4",
|
||||
"rustls",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"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",
|
||||
"webpki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1483,14 +1446,14 @@ dependencies = [
|
|||
"fxhash",
|
||||
"rand",
|
||||
"ring",
|
||||
"rustls 0.20.4",
|
||||
"rustls-native-certs 0.6.2",
|
||||
"rustls",
|
||||
"rustls-native-certs",
|
||||
"rustls-pemfile 0.2.1",
|
||||
"slab",
|
||||
"thiserror",
|
||||
"tinyvec",
|
||||
"tracing",
|
||||
"webpki 0.22.0",
|
||||
"webpki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1501,8 +1464,8 @@ checksum = "9f832d8958db3e84d2ec93b5eb2272b45aa23cf7f8fe6e79f578896f4e6c231b"
|
|||
dependencies = [
|
||||
"futures-util",
|
||||
"libc",
|
||||
"quinn-proto 0.8.4",
|
||||
"socket2 0.4.4",
|
||||
"quinn-proto",
|
||||
"socket2",
|
||||
"tokio",
|
||||
"tracing",
|
||||
]
|
||||
|
@ -1518,14 +1481,13 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.4"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8"
|
||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
"rand_hc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1547,15 +1509,6 @@ dependencies = [
|
|||
"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]]
|
||||
name = "rcgen"
|
||||
version = "0.8.13"
|
||||
|
@ -1637,7 +1590,7 @@ dependencies = [
|
|||
"native-tls",
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"rustls 0.20.4",
|
||||
"rustls",
|
||||
"rustls-pemfile 0.3.0",
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
@ -1724,19 +1677,6 @@ dependencies = [
|
|||
"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]]
|
||||
name = "rustls"
|
||||
version = "0.20.4"
|
||||
|
@ -1745,20 +1685,8 @@ checksum = "4fbfeb8d0ddb84706bc597a5574ab8912817c52a397f819e5b614e2265206921"
|
|||
dependencies = [
|
||||
"log",
|
||||
"ring",
|
||||
"sct 0.7.0",
|
||||
"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",
|
||||
"sct",
|
||||
"webpki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1843,16 +1771,6 @@ version = "1.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "sct"
|
||||
version = "0.7.0"
|
||||
|
@ -1984,17 +1902,6 @@ version = "1.7.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "socket2"
|
||||
version = "0.4.4"
|
||||
|
@ -2077,18 +1984,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.29"
|
||||
version = "1.0.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "602eca064b2d83369e2b2f34b09c70b605402801927c65c11071ac911d299b88"
|
||||
checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.29"
|
||||
version = "1.0.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bad553cc2c78e8de258400763a647e80e6d1b31ee237275d756f6836d204494c"
|
||||
checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -2132,20 +2039,20 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
|
|||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.17.0"
|
||||
version = "1.21.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2af73ac49756f3f7c01172e34a23e5d0216f6c32333757c2c61feb2bbff5a5ee"
|
||||
checksum = "a9e03c497dc955702ba729190dc4aac6f2a0ce97f913e5b1b5912fc5039d9099"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"bytes",
|
||||
"libc",
|
||||
"memchr",
|
||||
"mio 0.8.2",
|
||||
"mio",
|
||||
"num_cpus",
|
||||
"once_cell",
|
||||
"parking_lot",
|
||||
"pin-project-lite",
|
||||
"signal-hook-registry",
|
||||
"socket2 0.4.4",
|
||||
"socket2",
|
||||
"tokio-macros",
|
||||
"winapi",
|
||||
]
|
||||
|
@ -2177,9 +2084,9 @@ version = "0.23.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4151fda0cf2798550ad0b34bcfc9b9dcc2a9d2471c895c68f3a8818e54f2389e"
|
||||
dependencies = [
|
||||
"rustls 0.20.4",
|
||||
"rustls",
|
||||
"tokio",
|
||||
"webpki 0.22.0",
|
||||
"webpki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2542,16 +2449,6 @@ dependencies = [
|
|||
"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]]
|
||||
name = "webpki"
|
||||
version = "0.22.0"
|
||||
|
@ -2568,7 +2465,7 @@ version = "0.22.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44d8de8415c823c8abd270ad483c6feeac771fad964890779f9a8cb24fbbc1bf"
|
||||
dependencies = [
|
||||
"webpki 0.22.0",
|
||||
"webpki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2608,11 +2505,24 @@ version = "0.34.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5acdd78cb4ba54c0045ac14f62d8f94a03d10047904ae2a40afa1e99d8f70825"
|
||||
dependencies = [
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_msvc",
|
||||
"windows_aarch64_msvc 0.34.0",
|
||||
"windows_i686_gnu 0.34.0",
|
||||
"windows_i686_msvc 0.34.0",
|
||||
"windows_x86_64_gnu 0.34.0",
|
||||
"windows_x86_64_msvc 0.34.0",
|
||||
]
|
||||
|
||||
[[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]]
|
||||
|
@ -2621,30 +2531,60 @@ version = "0.34.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "17cffbe740121affb56fad0fc0e421804adf0ae00891205213b5cecd30db881d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.36.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.34.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2564fde759adb79129d9b4f54be42b32c89970c18ebf93124ca8870a498688ed"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.36.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.34.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9cd9d32ba70453522332c14d38814bceeb747d80b3958676007acadd7e166956"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.36.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.34.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.34.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "winreg"
|
||||
version = "0.10.1"
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
[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"] }
|
|
@ -0,0 +1,125 @@
|
|||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,299 @@
|
|||
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),
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
[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"
|
|
@ -0,0 +1,44 @@
|
|||
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 ())]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
pub fn main () {
|
||||
ptth_diceware::main ()
|
||||
}
|
|
@ -16,6 +16,7 @@ anyhow = "1.0.38"
|
|||
ctrlc = "3.2.1"
|
||||
futures-util = "0.3.9"
|
||||
hex = "0.4.3"
|
||||
ptth_diceware = { path = "../ptth_diceware" }
|
||||
ptth_file_server = { path = "../ptth_file_server_bin" }
|
||||
ptth_server = { path = "../ptth_server" }
|
||||
ptth_quic = { path = "../ptth_quic" }
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
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,7 +5,6 @@ use std::{
|
|||
|
||||
use tokio::sync::watch;
|
||||
|
||||
mod diceware;
|
||||
mod download;
|
||||
mod ulid;
|
||||
|
||||
|
@ -30,7 +29,7 @@ async fn main () -> anyhow::Result <()> {
|
|||
let (subcommand, args) = parse_args (&args)?;
|
||||
match subcommand {
|
||||
Diceware => {
|
||||
diceware::main ();
|
||||
ptth_diceware::main ();
|
||||
Ok (())
|
||||
},
|
||||
Download => download::main (args).await,
|
||||
|
|
|
@ -1,521 +1,30 @@
|
|||
use hyper::{
|
||||
Body,
|
||||
Request,
|
||||
Response,
|
||||
Server,
|
||||
service::{
|
||||
make_service_fn,
|
||||
service_fn,
|
||||
},
|
||||
StatusCode,
|
||||
};
|
||||
use structopt::StructOpt;
|
||||
use tokio::{
|
||||
net::UdpSocket,
|
||||
sync::watch,
|
||||
};
|
||||
use tokio::sync::watch;
|
||||
|
||||
use ptth_quic::prelude::*;
|
||||
use protocol::PeerId;
|
||||
|
||||
#[derive (Debug, StructOpt)]
|
||||
struct Opt {
|
||||
#[structopt (long)]
|
||||
listen_addr: Option <String>,
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main () -> anyhow::Result <()> {
|
||||
use structopt::StructOpt;
|
||||
|
||||
tracing_subscriber::fmt::init ();
|
||||
|
||||
let opt = Opt::from_args ();
|
||||
let opt = ptth_quic::executable_relay_server::Opt::from_args ();
|
||||
|
||||
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));
|
||||
let (running_tx, mut running_rx) = watch::channel (true);
|
||||
|
||||
tokio::fs::create_dir_all ("ptth_quic_output").await?;
|
||||
tokio::fs::write ("ptth_quic_output/quic_server.crt", &server_cert).await?;
|
||||
ctrlc::set_handler (move || {
|
||||
running_tx.send (false).expect ("Couldn't forward Ctrl+C signal");
|
||||
})?;
|
||||
trace! ("Set Ctrl+C handler");
|
||||
|
||||
let relay_state = Arc::new (RelayState::default ());
|
||||
tokio::select! {
|
||||
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?;
|
||||
},
|
||||
protocol::P3Peer::P4ServerProxy (peer) => {
|
||||
trace! ("Accepting connection from P4 end server");
|
||||
// TODO: Check authorization for P4 peers
|
||||
val = running_rx.changed () => {
|
||||
|
||||
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 (())
|
||||
}
|
||||
|
|
|
@ -0,0 +1,514 @@
|
|||
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,6 +1,7 @@
|
|||
pub mod client_proxy;
|
||||
pub mod connection;
|
||||
pub mod executable_end_server;
|
||||
pub mod executable_relay_server;
|
||||
pub mod prelude;
|
||||
pub mod protocol;
|
||||
pub mod quinn_utils;
|
||||
|
|
|
@ -12,7 +12,7 @@ anyhow = "1.0.38"
|
|||
blake3 = "1.0.0"
|
||||
fltk = "1.2.8"
|
||||
ptth_quic = { path = "../ptth_quic" }
|
||||
quinn = "0.7.2"
|
||||
quinn = "0.8.5"
|
||||
rand = "0.8.4"
|
||||
rand_chacha = "0.3.1"
|
||||
reqwest = "0.11.4"
|
||||
|
|
|
@ -238,7 +238,7 @@ fn main () -> anyhow::Result <()> {
|
|||
let quinn::NewConnection {
|
||||
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")?;
|
||||
|
||||
Ok::<_, anyhow::Error> (connection)
|
||||
|
|
Loading…
Reference in New Issue