aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorrustdesk <[email protected]>2022-05-12 20:00:33 +0800
committerrustdesk <[email protected]>2022-05-12 20:00:33 +0800
commitb3f39598a7324dacec0cd84d5e09b95724805cc8 (patch)
tree9a80ecd503ec53089bfd03d65612d10e615b76af
parentd36d6da4452f6250e4b9c9e821367e2dc6783f11 (diff)
downloadrustdesk-server-b3f39598a7324dacec0cd84d5e09b95724805cc8.tar.gz
rustdesk-server-b3f39598a7324dacec0cd84d5e09b95724805cc8.zip
change sled to sqlite and remove lic
-rw-r--r--.gitattributes1
-rw-r--r--.gitignore8
-rw-r--r--Cargo.lock2360
-rw-r--r--Cargo.toml47
-rw-r--r--Dockerfile4
-rw-r--r--README.md23
-rw-r--r--db_v2.sqlite3bin0 -> 24576 bytes
m---------libs/hbb_common0
-rwxr-xr-xspk/INFO18
-rwxr-xr-xspk/PACKAGE_ICON.PNGbin7482 -> 0 bytes
-rwxr-xr-xspk/PACKAGE_ICON_256.PNGbin31376 -> 0 bytes
-rwxr-xr-xspk/WIZARD_UIFILES/install_uifile54
-rwxr-xr-xspk/scripts/RustDesk_Server.sc23
-rwxr-xr-xspk/scripts/installer167
-rwxr-xr-xspk/scripts/postinst3
-rwxr-xr-xspk/scripts/postuninst3
-rwxr-xr-xspk/scripts/postupgrade3
-rwxr-xr-xspk/scripts/preinst3
-rwxr-xr-xspk/scripts/preuninst3
-rwxr-xr-xspk/scripts/preupgrade3
-rwxr-xr-xspk/scripts/start-stop-status158
-rw-r--r--src/common.rs128
-rw-r--r--src/database.rs231
-rw-r--r--src/hbbr.rs33
-rw-r--r--src/lib.rs6
-rw-r--r--src/lic.rs170
-rw-r--r--src/main.rs86
-rw-r--r--src/peer.rs185
-rw-r--r--src/protos/message.rs930
-rw-r--r--src/relay_server.rs614
-rw-r--r--src/rendezvous_server.rs1296
-rw-r--r--src/sled_async.rs101
-rw-r--r--src/version.rs1
33 files changed, 4071 insertions, 2591 deletions
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..176a458
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1 @@
+* text=auto
diff --git a/.gitignore b/.gitignore
index 892f3d3..b8d97d2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,2 @@
-/target
-**/*.rs.bk
-version.rs
-sled.db
-hbbs.sh
-hbbs.conf
+target
+id*
diff --git a/Cargo.lock b/Cargo.lock
index be7159e..8cdcc6b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1,10 +1,17 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
+version = 3
+
[[package]]
name = "ahash"
-version = "0.4.7"
+version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "739f4a8db6605981345c5654f3a85b056ce52f37a39d34da03f25bf2151ea16e"
+checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
+dependencies = [
+ "getrandom",
+ "once_cell",
+ "version_check",
+]
[[package]]
name = "aho-corasick"
@@ -17,18 +24,55 @@ dependencies = [
[[package]]
name = "ansi_term"
-version = "0.11.0"
+version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
+checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
dependencies = [
- "winapi 0.3.9",
+ "winapi",
]
[[package]]
name = "anyhow"
-version = "1.0.40"
+version = "1.0.57"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc"
+
+[[package]]
+name = "arrayvec"
+version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "28b2cd92db5cbd74e8e5028f7e27dd7aa3090e89e4f2a197cc7c8dfb69c7063b"
+checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
+
+[[package]]
+name = "async-speed-limit"
+version = "0.3.1"
+source = "git+https://github.com/open-trade/async-speed-limit#f89f702ae01d4016429543d2f0dda1086157e420"
+dependencies = [
+ "futures-core",
+ "futures-io",
+ "futures-timer",
+ "pin-project-lite",
+]
+
+[[package]]
+name = "async-trait"
+version = "0.1.53"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed6aa3524a2dfcf9fe180c51eae2b58738348d819517ceadf95789c51fff7600"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "atoi"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "616896e05fc0e2649463a93a15183c6a16bf03413a7af88ef1285ddedfa9cda5"
+dependencies = [
+ "num-traits",
+]
[[package]]
name = "atty"
@@ -38,14 +82,60 @@ checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi",
"libc",
- "winapi 0.3.9",
+ "winapi",
]
[[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 = "axum"
+version = "0.5.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "00f1e8a972137fad81e2a1a60b86ff17ce0338f8017264e45a9723d0083c39a1"
+dependencies = [
+ "async-trait",
+ "axum-core",
+ "bitflags",
+ "bytes",
+ "futures-util",
+ "headers",
+ "http",
+ "http-body",
+ "hyper",
+ "itoa",
+ "matchit",
+ "memchr",
+ "mime",
+ "percent-encoding",
+ "pin-project-lite",
+ "serde",
+ "serde_json",
+ "serde_urlencoded",
+ "sync_wrapper",
+ "tokio",
+ "tower",
+ "tower-http 0.3.3",
+ "tower-layer",
+ "tower-service",
+]
+
+[[package]]
+name = "axum-core"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da31c0ed7b4690e2c78fe4b880d21cd7db04a346ebc658b4270251b695437f17"
+dependencies = [
+ "async-trait",
+ "bytes",
+ "futures-util",
+ "http",
+ "http-body",
+ "mime",
+]
[[package]]
name = "base64"
@@ -54,59 +144,77 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
[[package]]
-name = "bindgen"
-version = "0.57.0"
+name = "bcrypt"
+version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fd4865004a46a0aafb2a0a5eb19d3c9fc46ee5f063a6cfc605c69ac9ecf5263d"
+checksum = "6fe4fef31efb0f76133ae8e3576a88e58edb7cfc5584c81c758c349ba46b43fc"
dependencies = [
- "bitflags",
- "cexpr",
- "clang-sys",
- "lazy_static",
- "lazycell",
- "peeking_take_while",
- "proc-macro2",
- "quote",
- "regex",
- "rustc-hash",
- "shlex",
+ "base64",
+ "blowfish",
+ "getrandom",
+ "zeroize",
]
[[package]]
name = "bitflags"
-version = "1.2.1"
+version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
-name = "bytes"
-version = "0.5.6"
+name = "block-buffer"
+version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38"
+checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
+dependencies = [
+ "generic-array",
+]
[[package]]
-name = "cc"
-version = "1.0.67"
+name = "block-buffer"
+version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd"
+checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324"
dependencies = [
- "jobserver",
+ "generic-array",
]
[[package]]
-name = "cexpr"
-version = "0.4.0"
+name = "blowfish"
+version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f4aedb84272dbe89af497cf81375129abda4fc0a9e7c5d317498c15cc30c0d27"
+checksum = "e412e2cd0f2b2d93e02543ceae7917b3c70331573df19ee046bcbc35e45e87d7"
dependencies = [
- "nom",
+ "byteorder",
+ "cipher",
]
[[package]]
-name = "cfg-if"
-version = "0.1.10"
+name = "bumpalo"
+version = "3.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899"
+
+[[package]]
+name = "byteorder"
+version = "1.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
+
+[[package]]
+name = "bytes"
+version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
+checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
+
+[[package]]
+name = "cc"
+version = "1.0.73"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
+dependencies = [
+ "jobserver",
+]
[[package]]
name = "cfg-if"
@@ -115,21 +223,33 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
-name = "clang-sys"
-version = "1.2.0"
+name = "chrono"
+version = "0.4.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "853eda514c284c2287f4bf20ae614f8781f40a81d32ecda6e91449304dfe077c"
+checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
dependencies = [
- "glob",
"libc",
- "libloading",
+ "num-integer",
+ "num-traits",
+ "time 0.1.43",
+ "winapi",
+]
+
+[[package]]
+name = "cipher"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d1873270f8f7942c191139cb8a40fd228da6c3fd2fc376d7e92d47aa14aeb59e"
+dependencies = [
+ "crypto-common",
+ "inout",
]
[[package]]
name = "clap"
-version = "2.33.3"
+version = "2.34.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
+checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
dependencies = [
"ansi_term",
"atty",
@@ -141,29 +261,176 @@ dependencies = [
]
[[package]]
+name = "config"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1b1b9d958c2b1368a663f05538fc1b5975adce1e19f435acceae987aceeeb369"
+dependencies = [
+ "lazy_static",
+ "nom 5.1.2",
+ "serde",
+]
+
+[[package]]
name = "confy"
-version = "0.4.1"
-source = "git+https://github.com/open-trade/confy#27fa12941291b44ccd856aef4a5452c1eb646047"
+version = "0.4.0"
+source = "git+https://github.com/open-trade/confy#630cc28a396cb7d01eefdd9f3824486fe4d8554b"
dependencies = [
- "directories",
+ "directories-next",
"serde",
+ "thiserror",
"toml",
]
[[package]]
-name = "cryptoxide"
-version = "0.3.3"
+name = "core-foundation"
+version = "0.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146"
+dependencies = [
+ "core-foundation-sys",
+ "libc",
+]
+
+[[package]]
+name = "core-foundation-sys"
+version = "0.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
+
+[[package]]
+name = "cpufeatures"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "crc"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49fc9a695bca7f35f5f4c15cddc84415f66a74ea78eef08e90c5024f2b540e23"
+dependencies = [
+ "crc-catalog",
+]
+
+[[package]]
+name = "crc-catalog"
+version = "1.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ccaeedb56da03b09f598226e25e80088cb4cd25f316e6e4df7d695f0feeb1403"
+
+[[package]]
+name = "crossbeam"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ae5588f6b3c3cb05239e90bd110f257254aecd01e4635400391aeae07497845"
+dependencies = [
+ "cfg-if",
+ "crossbeam-channel",
+ "crossbeam-deque",
+ "crossbeam-epoch",
+ "crossbeam-queue",
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-channel"
+version = "0.5.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5aaa7bd5fb665c6864b5f963dd9097905c54125909c7aa94c9e18507cdbe6c53"
+dependencies = [
+ "cfg-if",
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-deque"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e"
+dependencies = [
+ "cfg-if",
+ "crossbeam-epoch",
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-epoch"
+version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b8c4fdc86023bc33b265f256ce8205329125b86c38a8a96e243a6a705b7230ec"
+checksum = "1145cf131a2c6ba0615079ab6a638f7e1973ac9c2634fcbeaaad6114246efe8c"
+dependencies = [
+ "autocfg",
+ "cfg-if",
+ "crossbeam-utils",
+ "lazy_static",
+ "memoffset",
+ "scopeguard",
+]
[[package]]
-name = "directories"
-version = "2.0.2"
+name = "crossbeam-queue"
+version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "551a778172a450d7fc12e629ca3b0428d00f6afa9a43da1b630d54604e97371c"
+checksum = "1f25d8400f4a7a5778f0e4e52384a48cbd9b5c495d110786187fc750075277a2"
dependencies = [
- "cfg-if 0.1.10",
- "dirs-sys",
+ "cfg-if",
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-utils"
+version = "0.8.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38"
+dependencies = [
+ "cfg-if",
+ "lazy_static",
+]
+
+[[package]]
+name = "crypto-common"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "57952ca27b5e3606ff4dd79b0020231aaf9d6aa76dc05fd30137538c50bd3ce8"
+dependencies = [
+ "generic-array",
+ "typenum",
+]
+
+[[package]]
+name = "deadpool"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ef82259c587bceda08349f28ff00f69ae4c897898f254140af6021eb218e8232"
+dependencies = [
+ "async-trait",
+ "config",
+ "num_cpus",
+ "serde",
+ "tokio",
+]
+
+[[package]]
+name = "digest"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
+dependencies = [
+ "generic-array",
+]
+
+[[package]]
+name = "digest"
+version = "0.10.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506"
+dependencies = [
+ "block-buffer 0.10.2",
+ "crypto-common",
]
[[package]]
@@ -172,7 +439,7 @@ version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "339ee130d97a610ea5a5872d2bbb130fdf68884ff09d3028b81bec8a1ac23bbc"
dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if",
"dirs-sys-next",
]
@@ -182,22 +449,11 @@ version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1"
dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if",
"dirs-sys-next",
]
[[package]]
-name = "dirs-sys"
-version = "0.3.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "03d86534ed367a67548dc68113a0f5db55432fdfbb6e6f9d77704397d95d5780"
-dependencies = [
- "libc",
- "redox_users",
- "winapi 0.3.9",
-]
-
-[[package]]
name = "dirs-sys-next"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -205,23 +461,41 @@ checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d"
dependencies = [
"libc",
"redox_users",
- "winapi 0.3.9",
+ "winapi",
]
[[package]]
name = "dlv-list"
-version = "0.2.3"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0688c2a7f92e427f44895cd63841bff7b29f8d7a1648b9e7e07a4a365b2e1257"
+
+[[package]]
+name = "dotenv"
+version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "68df3f2b690c1b86e65ef7830956aededf3cb0a16f898f79b9a6f421a7b6211b"
+checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f"
+
+[[package]]
+name = "ed25519"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d916019f70ae3a1faa1195685e290287f39207d38e6dfee727197cffcc002214"
dependencies = [
- "rand",
+ "signature",
]
[[package]]
+name = "either"
+version = "1.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
+
+[[package]]
name = "env_logger"
-version = "0.8.3"
+version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "17392a012ea30ef05a610aa97dfb49496e71c9f676b27879922ea5bdf60d9d3f"
+checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3"
dependencies = [
"atty",
"humantime",
@@ -231,44 +505,78 @@ dependencies = [
]
[[package]]
+name = "fastrand"
+version = "1.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf"
+dependencies = [
+ "instant",
+]
+
+[[package]]
name = "filetime"
-version = "0.2.14"
+version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d34cfa13a63ae058bfa601fe9e313bbdb3746427c1459185464ce0fcf62e1e8"
+checksum = "c0408e2626025178a6a7f7ffc05a25bc47103229f19c113755de7bf63816290c"
dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if",
"libc",
"redox_syscall",
- "winapi 0.3.9",
+ "winapi",
]
[[package]]
-name = "fnv"
-version = "1.0.7"
+name = "flexi_logger"
+version = "0.22.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
+checksum = "969940c39bc718475391e53a3a59b0157e64929c80cf83ad5dde5f770ecdc423"
+dependencies = [
+ "ansi_term",
+ "atty",
+ "chrono",
+ "crossbeam",
+ "glob",
+ "lazy_static",
+ "log",
+ "regex",
+ "rustversion",
+ "thiserror",
+ "time 0.3.9",
+]
[[package]]
-name = "fuchsia-zircon"
-version = "0.3.3"
+name = "flume"
+version = "0.10.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
+checksum = "843c03199d0c0ca54bc1ea90ac0d507274c28abcc4f691ae8b4eaa375087c76a"
dependencies = [
- "bitflags",
- "fuchsia-zircon-sys",
+ "futures-core",
+ "futures-sink",
+ "pin-project",
+ "spin 0.9.3",
]
[[package]]
-name = "fuchsia-zircon-sys"
-version = "0.3.3"
+name = "fnv"
+version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
+checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
+
+[[package]]
+name = "form_urlencoded"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191"
+dependencies = [
+ "matches",
+ "percent-encoding",
+]
[[package]]
name = "futures"
-version = "0.3.15"
+version = "0.3.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0e7e43a803dae2fa37c1f6a8fe121e1f7bf9548b4dfc0522a42f34145dadfc27"
+checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e"
dependencies = [
"futures-channel",
"futures-core",
@@ -281,9 +589,9 @@ dependencies = [
[[package]]
name = "futures-channel"
-version = "0.3.15"
+version = "0.3.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e682a68b29a882df0545c143dc3646daefe80ba479bcdede94d5a703de2871e2"
+checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010"
dependencies = [
"futures-core",
"futures-sink",
@@ -291,15 +599,15 @@ dependencies = [
[[package]]
name = "futures-core"
-version = "0.3.15"
+version = "0.3.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0402f765d8a89a26043b889b26ce3c4679d268fa6bb22cd7c6aad98340e179d1"
+checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3"
[[package]]
name = "futures-executor"
-version = "0.3.15"
+version = "0.3.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "badaa6a909fac9e7236d0620a2f57f7664640c56575b71a7552fbd68deafab79"
+checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6"
dependencies = [
"futures-core",
"futures-task",
@@ -307,19 +615,28 @@ dependencies = [
]
[[package]]
+name = "futures-intrusive"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "62007592ac46aa7c2b6416f7deb9a8a8f63a01e0f1d6e1787d5630170db2b63e"
+dependencies = [
+ "futures-core",
+ "lock_api",
+ "parking_lot 0.11.2",
+]
+
+[[package]]
name = "futures-io"
-version = "0.3.15"
+version = "0.3.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "acc499defb3b348f8d8f3f66415835a9131856ff7714bf10dadfc4ec4bdb29a1"
+checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b"
[[package]]
name = "futures-macro"
-version = "0.3.15"
+version = "0.3.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a4c40298486cdf52cc00cd6d6987892ba502c7656a16a4192a9992b1ccedd121"
+checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512"
dependencies = [
- "autocfg",
- "proc-macro-hack",
"proc-macro2",
"quote",
"syn",
@@ -327,23 +644,28 @@ dependencies = [
[[package]]
name = "futures-sink"
-version = "0.3.15"
+version = "0.3.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a57bead0ceff0d6dde8f465ecd96c9338121bb7717d3e7b108059531870c4282"
+checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868"
[[package]]
name = "futures-task"
-version = "0.3.15"
+version = "0.3.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a16bef9fc1a4dddb5bee51c989e3fbba26569cbb0e31f5b303c184e3dd33dae"
+checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a"
+
+[[package]]
+name = "futures-timer"
+version = "3.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c"
[[package]]
name = "futures-util"
-version = "0.3.15"
+version = "0.3.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "feb5c238d27e2bf94ffdfd27b2c29e3df4a68c4193bb6427384259e2bf191967"
+checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a"
dependencies = [
- "autocfg",
"futures-channel",
"futures-core",
"futures-io",
@@ -351,22 +673,39 @@ dependencies = [
"futures-sink",
"futures-task",
"memchr",
- "pin-project-lite 0.2.6",
+ "pin-project-lite",
"pin-utils",
- "proc-macro-hack",
- "proc-macro-nested",
"slab",
]
[[package]]
+name = "fxhash"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
+dependencies = [
+ "byteorder",
+]
+
+[[package]]
+name = "generic-array"
+version = "0.14.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803"
+dependencies = [
+ "typenum",
+ "version_check",
+]
+
+[[package]]
name = "getrandom"
-version = "0.2.2"
+version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8"
+checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad"
dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if",
"libc",
- "wasi",
+ "wasi 0.10.2+wasi-snapshot-preview1",
]
[[package]]
@@ -377,14 +716,32 @@ checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
[[package]]
name = "hashbrown"
-version = "0.9.1"
+version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04"
+checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
dependencies = [
"ahash",
]
[[package]]
+name = "hashbrown"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "db0d4cf898abf0081f964436dc980e96670a0f36863e4b83aaacdb65c9d7ccc3"
+dependencies = [
+ "ahash",
+]
+
+[[package]]
+name = "hashlink"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7249a3129cbc1ffccd74857f81464a323a152173cdb134e0fd81bc803b29facf"
+dependencies = [
+ "hashbrown 0.11.2",
+]
+
+[[package]]
name = "hbb_common"
version = "0.1.0"
dependencies = [
@@ -402,87 +759,260 @@ dependencies = [
"mac_address",
"protobuf",
"protobuf-codegen-pure",
+ "quinn",
"rand",
"regex",
"serde",
"serde_derive",
"serde_json",
- "socket2",
+ "socket2 0.3.19",
"sodiumoxide",
"tokio",
- "tokio-util",
+ "tokio-socks",
+ "tokio-util 0.6.9",
"toml",
- "winapi 0.3.9",
+ "winapi",
"zstd",
]
[[package]]
name = "hbbs"
-version = "1.1.4"
+version = "1.1.5"
dependencies = [
+ "async-speed-limit",
+ "async-trait",
+ "axum",
"base64",
+ "bcrypt",
+ "chrono",
"clap",
- "cryptoxide",
+ "deadpool",
+ "flexi_logger",
"hbb_common",
+ "headers",
+ "http",
+ "jsonwebtoken",
"lazy_static",
"mac_address",
"machine-uid",
"minreq",
- "rocksdb",
+ "once_cell",
+ "regex",
"rust-ini",
"serde",
"serde_derive",
"serde_json",
+ "sodiumoxide",
+ "sqlx",
+ "tokio-tungstenite",
+ "tower-http 0.2.5",
+ "tungstenite",
+ "uuid",
"whoami",
]
[[package]]
+name = "headers"
+version = "0.3.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4cff78e5788be1e0ab65b04d306b2ed5092c815ec97ec70f4ebd5aee158aa55d"
+dependencies = [
+ "base64",
+ "bitflags",
+ "bytes",
+ "headers-core",
+ "http",
+ "httpdate",
+ "mime",
+ "sha-1",
+]
+
+[[package]]
+name = "headers-core"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429"
+dependencies = [
+ "http",
+]
+
+[[package]]
+name = "heck"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c"
+dependencies = [
+ "unicode-segmentation",
+]
+
+[[package]]
name = "hermit-abi"
-version = "0.1.18"
+version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c"
+checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
dependencies = [
"libc",
]
[[package]]
+name = "hex"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
+
+[[package]]
+name = "http"
+version = "0.2.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ff8670570af52249509a86f5e3e18a08c60b177071826898fde8997cf5f6bfbb"
+dependencies = [
+ "bytes",
+ "fnv",
+ "itoa",
+]
+
+[[package]]
+name = "http-body"
+version = "0.4.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1ff4f84919677303da5f147645dbea6b1881f368d03ac84e1dc09031ebd7b2c6"
+dependencies = [
+ "bytes",
+ "http",
+ "pin-project-lite",
+]
+
+[[package]]
+name = "http-range-header"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0bfe8eed0a9285ef776bb792479ea3834e8b94e13d615c2f66d03dd50a435a29"
+
+[[package]]
+name = "httparse"
+version = "1.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "496ce29bb5a52785b44e0f7ca2847ae0bb839c9bd28f69acac9b99d461c0c04c"
+
+[[package]]
+name = "httpdate"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
+
+[[package]]
name = "humantime"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
[[package]]
-name = "iovec"
-version = "0.1.4"
+name = "hyper"
+version = "0.14.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e"
+checksum = "b26ae0a80afebe130861d90abf98e3814a4f28a4c6ffeb5ab8ebb2be311e0ef2"
dependencies = [
- "libc",
+ "bytes",
+ "futures-channel",
+ "futures-core",
+ "futures-util",
+ "http",
+ "http-body",
+ "httparse",
+ "httpdate",
+ "itoa",
+ "pin-project-lite",
+ "socket2 0.4.4",
+ "tokio",
+ "tower-service",
+ "tracing",
+ "want",
+]
+
+[[package]]
+name = "idna"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8"
+dependencies = [
+ "matches",
+ "unicode-bidi",
+ "unicode-normalization",
+]
+
+[[package]]
+name = "indexmap"
+version = "1.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee"
+dependencies = [
+ "autocfg",
+ "hashbrown 0.11.2",
+]
+
+[[package]]
+name = "inout"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5"
+dependencies = [
+ "generic-array",
+]
+
+[[package]]
+name = "instant"
+version = "0.1.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "itertools"
+version = "0.10.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3"
+dependencies = [
+ "either",
]
[[package]]
name = "itoa"
-version = "0.4.7"
+version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
+checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35"
[[package]]
name = "jobserver"
-version = "0.1.22"
+version = "0.1.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "972f5ae5d1cb9c6ae417789196c803205313edde988685da5e3aae0827b9e7fd"
+checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa"
dependencies = [
"libc",
]
[[package]]
-name = "kernel32-sys"
-version = "0.2.2"
+name = "js-sys"
+version = "0.3.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
+checksum = "671a26f820db17c2a2750743f1dd03bafd15b98c9f30c7c2628c024c05d73397"
dependencies = [
- "winapi 0.2.8",
- "winapi-build",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "jsonwebtoken"
+version = "8.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cc9051c17f81bae79440afa041b3a278e1de71bfb96d32454b477fd4703ccb6f"
+dependencies = [
+ "base64",
+ "pem",
+ "ring",
+ "serde",
+ "serde_json",
+ "simple_asn1",
]
[[package]]
@@ -492,67 +1022,74 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
-name = "lazycell"
-version = "1.3.0"
+name = "lexical-core"
+version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
+checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe"
+dependencies = [
+ "arrayvec",
+ "bitflags",
+ "cfg-if",
+ "ryu",
+ "static_assertions",
+]
[[package]]
name = "libc"
-version = "0.2.94"
+version = "0.2.125"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "18794a8ad5b29321f790b55d93dfba91e125cb1a9edbd4f8e3150acc771c1a5e"
+checksum = "5916d2ae698f6de9bfb891ad7a8d65c09d232dc58cc4ac433c7da3b2fd84bc2b"
[[package]]
-name = "libloading"
-version = "0.7.0"
+name = "libsodium-sys"
+version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6f84d96438c15fcd6c3f244c8fce01d1e2b9c6b5623e9c711dc9286d8fc92d6a"
+checksum = "6b779387cd56adfbc02ea4a668e704f729be8d6a6abd2c27ca5ee537849a92fd"
dependencies = [
- "cfg-if 1.0.0",
- "winapi 0.3.9",
+ "cc",
+ "libc",
+ "pkg-config",
+ "walkdir",
]
[[package]]
-name = "librocksdb-sys"
-version = "6.17.3"
+name = "libsqlite3-sys"
+version = "0.23.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5da125e1c0f22c7cae785982115523a0738728498547f415c9054cb17c7e89f9"
+checksum = "d2cafc7c74096c336d9d27145f7ebd4f4b6f95ba16aa5a282387267e6925cb58"
dependencies = [
- "bindgen",
"cc",
- "glob",
- "libc",
+ "pkg-config",
+ "vcpkg",
]
[[package]]
-name = "libsodium-sys"
-version = "0.2.6"
+name = "lock_api"
+version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a685b64f837b339074115f2e7f7b431ac73681d08d75b389db7498b8892b8a58"
+checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53"
dependencies = [
- "cc",
- "libc",
- "pkg-config",
+ "autocfg",
+ "scopeguard",
]
[[package]]
name = "log"
-version = "0.4.14"
+version = "0.4.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
+checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if",
]
[[package]]
name = "mac_address"
-version = "1.1.1"
+version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6d9bb26482176bddeea173ceaa2acec85146d20cdcc631eafaf9d605d3d4fc23"
+checksum = "df1d1bc1084549d60725ccc53a2bfa07f67fe4689fda07b05a36531f2988104a"
dependencies = [
"nix",
- "winapi 0.3.9",
+ "winapi",
]
[[package]]
@@ -565,72 +1102,87 @@ dependencies = [
]
[[package]]
+name = "matches"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
+
+[[package]]
+name = "matchit"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73cbba799671b762df5a175adf59ce145165747bb891505c43d09aefbbf38beb"
+
+[[package]]
name = "memchr"
-version = "2.4.0"
+version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
+checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
-name = "minreq"
-version = "2.3.1"
+name = "memoffset"
+version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "781e56f7d29192378f0a04948b1e6aec67ce561273b2dd26ac510bbe88d7be70"
+checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
dependencies = [
- "punycode",
+ "autocfg",
]
[[package]]
-name = "mio"
-version = "0.6.23"
+name = "mime"
+version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4afd66f5b91bf2a3bc13fad0e21caedac168ca4c707504e75585648ae80e4cc4"
+checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
+
+[[package]]
+name = "mime_guess"
+version = "2.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef"
dependencies = [
- "cfg-if 0.1.10",
- "fuchsia-zircon",
- "fuchsia-zircon-sys",
- "iovec",
- "kernel32-sys",
- "libc",
- "log",
- "miow 0.2.2",
- "net2",
- "slab",
- "winapi 0.2.8",
+ "mime",
+ "unicase",
]
[[package]]
-name = "mio-named-pipes"
-version = "0.1.7"
+name = "minimal-lexical"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
+
+[[package]]
+name = "minreq"
+version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0840c1c50fd55e521b247f949c241c9997709f23bd7f023b9762cd561e935656"
+checksum = "4c785bc6027fd359756e538541c8624012ba3776d3d3fe123885643092ed4132"
dependencies = [
"log",
- "mio",
- "miow 0.3.7",
- "winapi 0.3.9",
+ "punycode",
]
[[package]]
-name = "mio-uds"
-version = "0.6.8"
+name = "mio"
+version = "0.7.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "afcb699eb26d4332647cc848492bbc15eafb26f08d0304550d5aa1f612e066f0"
+checksum = "8067b404fe97c70829f082dec8bcf4f71225d7eaea1d8645349cb76fa06205cc"
dependencies = [
- "iovec",
"libc",
- "mio",
+ "log",
+ "miow",
+ "ntapi",
+ "winapi",
]
[[package]]
-name = "miow"
-version = "0.2.2"
+name = "mio"
+version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d"
+checksum = "713d550d9b44d89174e066b7a6217ae06234c10cb47819a88290d2b353c31799"
dependencies = [
- "kernel32-sys",
- "net2",
- "winapi 0.2.8",
- "ws2_32-sys",
+ "libc",
+ "log",
+ "wasi 0.11.0+wasi-snapshot-preview1",
+ "windows-sys",
]
[[package]]
@@ -639,30 +1191,20 @@ version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21"
dependencies = [
- "winapi 0.3.9",
-]
-
-[[package]]
-name = "net2"
-version = "0.2.37"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "391630d12b68002ae1e25e8f974306474966550ad82dac6886fb8910c19568ae"
-dependencies = [
- "cfg-if 0.1.10",
- "libc",
- "winapi 0.3.9",
+ "winapi",
]
[[package]]
name = "nix"
-version = "0.19.1"
+version = "0.23.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b2ccba0cfe4fdf15982d1674c69b1fd80bad427d293849982668dfe454bd61f2"
+checksum = "9f866317acbd3a240710c63f065ffb1e4fd466259045ccb504130b7f668f35c6"
dependencies = [
"bitflags",
"cc",
- "cfg-if 1.0.0",
+ "cfg-if",
"libc",
+ "memoffset",
]
[[package]]
@@ -671,107 +1213,283 @@ version = "5.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af"
dependencies = [
+ "lexical-core",
"memchr",
"version_check",
]
[[package]]
+name = "nom"
+version = "7.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36"
+dependencies = [
+ "memchr",
+ "minimal-lexical",
+]
+
+[[package]]
+name = "ntapi"
+version = "0.3.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
+name = "num-bigint"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f"
+dependencies = [
+ "autocfg",
+ "num-integer",
+ "num-traits",
+]
+
+[[package]]
+name = "num-integer"
+version = "0.1.45"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
+dependencies = [
+ "autocfg",
+ "num-traits",
+]
+
+[[package]]
+name = "num-traits"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
name = "num_cpus"
-version = "1.13.0"
+version = "1.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
+checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1"
dependencies = [
"hermit-abi",
"libc",
]
[[package]]
+name = "num_threads"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "once_cell"
+version = "1.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9"
+
+[[package]]
+name = "opaque-debug"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
+
+[[package]]
+name = "openssl-probe"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
+
+[[package]]
name = "ordered-multimap"
-version = "0.3.1"
+version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1c672c7ad9ec066e428c00eb917124a06f08db19e2584de982cc34b1f4c12485"
+checksum = "ccd746e37177e1711c20dd619a1620f34f5c8b569c53590a72dedd5344d8924a"
dependencies = [
"dlv-list",
- "hashbrown",
+ "hashbrown 0.12.1",
]
[[package]]
-name = "peeking_take_while"
-version = "0.1.2"
+name = "parking_lot"
+version = "0.11.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99"
+dependencies = [
+ "instant",
+ "lock_api",
+ "parking_lot_core 0.8.5",
+]
+
+[[package]]
+name = "parking_lot"
+version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
+checksum = "87f5ec2493a61ac0506c0f4199f99070cbe83857b0337006a30f3e6719b8ef58"
+dependencies = [
+ "lock_api",
+ "parking_lot_core 0.9.3",
+]
[[package]]
-name = "pin-project-lite"
-version = "0.1.12"
+name = "parking_lot_core"
+version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "257b64915a082f7811703966789728173279bdebb956b143dbcd23f6f970a777"
+checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216"
+dependencies = [
+ "cfg-if",
+ "instant",
+ "libc",
+ "redox_syscall",
+ "smallvec",
+ "winapi",
+]
[[package]]
-name = "pin-project-lite"
-version = "0.2.6"
+name = "parking_lot_core"
+version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc0e1f259c92177c30a4c9d177246edd0a3568b25756a977d0632cf8fa37e905"
+checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "redox_syscall",
+ "smallvec",
+ "windows-sys",
+]
[[package]]
-name = "pin-utils"
-version = "0.1.0"
+name = "paste"
+version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
+checksum = "0c520e05135d6e763148b6426a837e239041653ba7becd2e538c076c738025fc"
[[package]]
-name = "pkg-config"
-version = "0.3.19"
+name = "pem"
+version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c"
+checksum = "e9a3b09a20e374558580a4914d3b7d89bd61b954a5a5e1dcbea98753addb1947"
+dependencies = [
+ "base64",
+]
[[package]]
-name = "ppv-lite86"
-version = "0.2.10"
+name = "percent-encoding"
+version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
+checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
[[package]]
-name = "proc-macro-hack"
-version = "0.5.19"
+name = "pin-project"
+version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
+checksum = "58ad3879ad3baf4e44784bc6a718a8698867bb991f8ce24d1bcbe2cfb4c3a75e"
+dependencies = [
+ "pin-project-internal",
+]
[[package]]
-name = "proc-macro-nested"
-version = "0.1.7"
+name = "pin-project-internal"
+version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086"
+checksum = "744b6f092ba29c3650faf274db506afd39944f48420f6c86b17cfe0ee1cb36bb"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "pin-project-lite"
+version = "0.2.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
+
+[[package]]
+name = "pin-utils"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
+
+[[package]]
+name = "pkg-config"
+version = "0.3.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae"
+
+[[package]]
+name = "ppv-lite86"
+version = "0.2.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
[[package]]
name = "proc-macro2"
-version = "1.0.26"
+version = "1.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec"
+checksum = "9027b48e9d4c9175fa2218adf3557f91c1137021739951d4932f5f8268ac48aa"
dependencies = [
"unicode-xid",
]
[[package]]
name = "protobuf"
-version = "3.0.0-pre"
-source = "git+https://github.com/stepancheg/rust-protobuf#bbe35a98e196c4dea67dd23ac93c0a66ca11b903"
+version = "3.0.0-alpha.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9d5ef59c35c7472ce5e1b6c5924b87585143d1fc2cf39eae0009bba6c4df62f1"
[[package]]
name = "protobuf-codegen"
-version = "3.0.0-pre"
-source = "git+https://github.com/stepancheg/rust-protobuf#bbe35a98e196c4dea67dd23ac93c0a66ca11b903"
+version = "3.0.0-alpha.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "89100ee819f69b77a4cab389fec9dd155a305af4c615e6413ec1ef9341f333ef"
dependencies = [
+ "anyhow",
"protobuf",
+ "protobuf-parse",
+ "thiserror",
]
[[package]]
name = "protobuf-codegen-pure"
-version = "3.0.0-pre"
-source = "git+https://github.com/stepancheg/rust-protobuf#bbe35a98e196c4dea67dd23ac93c0a66ca11b903"
+version = "3.0.0-alpha.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "79453e74d08190551e821533ee42c447f9e21ca26f83520e120e6e8af27f6879"
dependencies = [
+ "anyhow",
"protobuf",
"protobuf-codegen",
+ "protobuf-parse",
+ "thiserror",
+]
+
+[[package]]
+name = "protobuf-parse"
+version = "3.0.0-alpha.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c265ffc69976efc3056955b881641add3186ad0be893ef10622482d80d1d2b68"
+dependencies = [
+ "anyhow",
+ "protobuf",
+ "protoc",
+ "tempfile",
+ "thiserror",
+]
+
+[[package]]
+name = "protoc"
+version = "3.0.0-alpha.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1f1f8b318a54d18fbe542513331e058f4f8ce6502e542e057c50c7e5e803fdab"
+dependencies = [
+ "anyhow",
+ "log",
+ "thiserror",
+ "which",
]
[[package]]
@@ -781,31 +1499,93 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e9e1dcb320d6839f6edb64f7a4a59d39b30480d4d1765b56873f7c858538a5fe"
[[package]]
+name = "quickcheck"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "588f6378e4dd99458b60ec275b4477add41ce4fa9f64dcba6f15adccb19b50d6"
+dependencies = [
+ "rand",
+]
+
+[[package]]
+name = "quinn"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d147472bc9a09f13b06c044787b6683cdffa02e2865b7f0fb53d67c49ed2988e"
+dependencies = [
+ "bytes",
+ "futures-channel",
+ "futures-util",
+ "fxhash",
+ "quinn-proto",
+ "quinn-udp",
+ "rustls 0.20.4",
+ "thiserror",
+ "tokio",
+ "tracing",
+ "webpki 0.22.0",
+]
+
+[[package]]
+name = "quinn-proto"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "359c5eb33845f3ee05c229e65f87cdbc503eea394964b8f1330833d460b4ff3e"
+dependencies = [
+ "bytes",
+ "fxhash",
+ "rand",
+ "ring",
+ "rustls 0.20.4",
+ "rustls-native-certs",
+ "rustls-pemfile 0.2.1",
+ "slab",
+ "thiserror",
+ "tinyvec",
+ "tracing",
+ "webpki 0.22.0",
+]
+
+[[package]]
+name = "quinn-udp"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "df185e5e5f7611fa6e628ed8f9633df10114b03bbaecab186ec55822c44ac727"
+dependencies = [
+ "futures-util",
+ "libc",
+ "mio 0.7.14",
+ "quinn-proto",
+ "socket2 0.4.4",
+ "tokio",
+ "tracing",
+]
+
+[[package]]
name = "quote"
-version = "1.0.9"
+version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
+checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rand"
-version = "0.8.3"
+version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e"
+checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
- "rand_hc",
]
[[package]]
name = "rand_chacha"
-version = "0.3.0"
+version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d"
+checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
@@ -813,46 +1593,38 @@ dependencies = [
[[package]]
name = "rand_core"
-version = "0.6.2"
+version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7"
+checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
dependencies = [
"getrandom",
]
[[package]]
-name = "rand_hc"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73"
-dependencies = [
- "rand_core",
-]
-
-[[package]]
name = "redox_syscall"
-version = "0.2.8"
+version = "0.2.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "742739e41cd49414de871ea5e549afb7e2a3ac77b589bcbebe8c82fab37147fc"
+checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42"
dependencies = [
"bitflags",
]
[[package]]
name = "redox_users"
-version = "0.4.0"
+version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64"
+checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b"
dependencies = [
"getrandom",
"redox_syscall",
+ "thiserror",
]
[[package]]
name = "regex"
-version = "1.5.4"
+version = "1.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
+checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286"
dependencies = [
"aho-corasick",
"memchr",
@@ -866,48 +1638,187 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
[[package]]
-name = "rocksdb"
-version = "0.15.0"
+name = "remove_dir_all"
+version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "23d83c02c429044d58474eaf5ae31e062d0de894e21125b47437ec0edc1397e6"
+checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
dependencies = [
+ "winapi",
+]
+
+[[package]]
+name = "ring"
+version = "0.16.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
+dependencies = [
+ "cc",
"libc",
- "librocksdb-sys",
+ "once_cell",
+ "spin 0.5.2",
+ "untrusted",
+ "web-sys",
+ "winapi",
]
[[package]]
name = "rust-ini"
-version = "0.16.1"
+version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "55b134767a87e0b086f73a4ce569ac9ce7d202f39c8eab6caa266e2617e73ac6"
+checksum = "f6d5f2436026b4f6e79dc829837d467cc7e9a55ee40e750d716713540715a2df"
dependencies = [
- "cfg-if 0.1.10",
+ "cfg-if",
"ordered-multimap",
]
[[package]]
-name = "rustc-hash"
-version = "1.1.0"
+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"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4fbfeb8d0ddb84706bc597a5574ab8912817c52a397f819e5b614e2265206921"
+dependencies = [
+ "ring",
+ "sct 0.7.0",
+ "webpki 0.22.0",
+]
+
+[[package]]
+name = "rustls-native-certs"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0167bac7a9f490495f3c33013e7722b53cb087ecbe082fb0c6387c96f634ea50"
+dependencies = [
+ "openssl-probe",
+ "rustls-pemfile 1.0.0",
+ "schannel",
+ "security-framework",
+]
+
+[[package]]
+name = "rustls-pemfile"
+version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
+checksum = "5eebeaeb360c87bfb72e84abdb3447159c0eaececf1bef2aecd65a8be949d1c9"
+dependencies = [
+ "base64",
+]
+
+[[package]]
+name = "rustls-pemfile"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e7522c9de787ff061458fe9a829dc790a3f5b22dc571694fc5883f448b94d9a9"
+dependencies = [
+ "base64",
+]
+
+[[package]]
+name = "rustversion"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f"
[[package]]
name = "ryu"
-version = "1.0.5"
+version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
+checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f"
+
+[[package]]
+name = "same-file"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
+dependencies = [
+ "winapi-util",
+]
+
+[[package]]
+name = "schannel"
+version = "0.1.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75"
+dependencies = [
+ "lazy_static",
+ "winapi",
+]
+
+[[package]]
+name = "scopeguard"
+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"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4"
+dependencies = [
+ "ring",
+ "untrusted",
+]
+
+[[package]]
+name = "security-framework"
+version = "2.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2dc14f172faf8a0194a3aded622712b0de276821addc574fa54fc0a1167e10dc"
+dependencies = [
+ "bitflags",
+ "core-foundation",
+ "core-foundation-sys",
+ "libc",
+ "security-framework-sys",
+]
+
+[[package]]
+name = "security-framework-sys"
+version = "2.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556"
+dependencies = [
+ "core-foundation-sys",
+ "libc",
+]
[[package]]
name = "serde"
-version = "1.0.126"
+version = "1.0.137"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03"
+checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1"
+dependencies = [
+ "serde_derive",
+]
[[package]]
name = "serde_derive"
-version = "1.0.126"
+version = "1.0.137"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "963a7dbc9895aeac7ac90e74f34a5d5261828f79df35cbed41e10189d3804d43"
+checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be"
dependencies = [
"proc-macro2",
"quote",
@@ -916,9 +1827,9 @@ dependencies = [
[[package]]
name = "serde_json"
-version = "1.0.64"
+version = "1.0.81"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79"
+checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c"
dependencies = [
"itoa",
"ryu",
@@ -926,25 +1837,79 @@ dependencies = [
]
[[package]]
-name = "shlex"
-version = "0.1.1"
+name = "serde_urlencoded"
+version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2"
+checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
+dependencies = [
+ "form_urlencoded",
+ "itoa",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "sha-1"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "028f48d513f9678cda28f6e4064755b3fbb2af6acd672f2c209b62323f7aea0f"
+dependencies = [
+ "cfg-if",
+ "cpufeatures",
+ "digest 0.10.3",
+]
+
+[[package]]
+name = "sha2"
+version = "0.9.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800"
+dependencies = [
+ "block-buffer 0.9.0",
+ "cfg-if",
+ "cpufeatures",
+ "digest 0.9.0",
+ "opaque-debug",
+]
[[package]]
name = "signal-hook-registry"
-version = "1.3.0"
+version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "16f1d0fef1604ba8f7a073c7e701f213e056707210e9020af4528e0101ce11a6"
+checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0"
dependencies = [
"libc",
]
[[package]]
+name = "signature"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f054c6c1a6e95179d6f23ed974060dcefb2d9388bb7256900badad682c499de4"
+
+[[package]]
+name = "simple_asn1"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4a762b1c38b9b990c694b9c2f8abe3372ce6a9ceaae6bca39cfc46e054f45745"
+dependencies = [
+ "num-bigint",
+ "num-traits",
+ "thiserror",
+ "time 0.3.9",
+]
+
+[[package]]
name = "slab"
-version = "0.4.3"
+version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f173ac3d1a7e3b28003f40de0b5ce7fe2710f9b9dc3fc38664cebee46b3b6527"
+checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32"
+
+[[package]]
+name = "smallvec"
+version = "1.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83"
[[package]]
name = "socket2"
@@ -952,23 +1917,160 @@ version = "0.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "122e570113d28d773067fab24266b66753f6ea915758651696b6e35e49f88d6e"
dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if",
+ "libc",
+ "winapi",
+]
+
+[[package]]
+name = "socket2"
+version = "0.4.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0"
+dependencies = [
"libc",
- "winapi 0.3.9",
+ "winapi",
]
[[package]]
name = "sodiumoxide"
-version = "0.2.6"
+version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7038b67c941e23501573cb7242ffb08709abe9b11eb74bceff875bbda024a6a8"
+checksum = "e26be3acb6c2d9a7aac28482586a7856436af4cfe7100031d219de2d2ecb0028"
dependencies = [
+ "ed25519",
"libc",
"libsodium-sys",
"serde",
]
[[package]]
+name = "spin"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
+
+[[package]]
+name = "spin"
+version = "0.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c530c2b0d0bf8b69304b39fe2001993e267461948b890cd037d8ad4293fa1a0d"
+dependencies = [
+ "lock_api",
+]
+
+[[package]]
+name = "sqlformat"
+version = "0.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b4b7922be017ee70900be125523f38bdd644f4f06a1b16e8fa5a8ee8c34bffd4"
+dependencies = [
+ "itertools",
+ "nom 7.1.1",
+ "unicode_categories",
+]
+
+[[package]]
+name = "sqlx"
+version = "0.5.11"
+source = "git+https://github.com/open-trade/sqlx#81392f03ba36fbd670447517dbc122fddb206de7"
+dependencies = [
+ "sqlx-core",
+ "sqlx-macros",
+]
+
+[[package]]
+name = "sqlx-core"
+version = "0.5.11"
+source = "git+https://github.com/open-trade/sqlx#81392f03ba36fbd670447517dbc122fddb206de7"
+dependencies = [
+ "ahash",
+ "atoi",
+ "bitflags",
+ "byteorder",
+ "bytes",
+ "chrono",
+ "crc",
+ "crossbeam-queue",
+ "either",
+ "flume",
+ "futures-channel",
+ "futures-core",
+ "futures-executor",
+ "futures-intrusive",
+ "futures-util",
+ "hashlink",
+ "hex",
+ "indexmap",
+ "itoa",
+ "libc",
+ "libsqlite3-sys",
+ "log",
+ "memchr",
+ "once_cell",
+ "paste",
+ "percent-encoding",
+ "rustls 0.19.1",
+ "serde",
+ "serde_json",
+ "sha2",
+ "smallvec",
+ "sqlformat",
+ "sqlx-rt",
+ "stringprep",
+ "thiserror",
+ "tokio-stream",
+ "url",
+ "webpki 0.21.4",
+ "webpki-roots",
+]
+
+[[package]]
+name = "sqlx-macros"
+version = "0.5.11"
+source = "git+https://github.com/open-trade/sqlx#81392f03ba36fbd670447517dbc122fddb206de7"
+dependencies = [
+ "dotenv",
+ "either",
+ "heck",
+ "once_cell",
+ "proc-macro2",
+ "quote",
+ "serde_json",
+ "sha2",
+ "sqlx-core",
+ "sqlx-rt",
+ "syn",
+ "url",
+]
+
+[[package]]
+name = "sqlx-rt"
+version = "0.5.11"
+source = "git+https://github.com/open-trade/sqlx#81392f03ba36fbd670447517dbc122fddb206de7"
+dependencies = [
+ "once_cell",
+ "tokio",
+ "tokio-rustls",
+]
+
+[[package]]
+name = "static_assertions"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
+
+[[package]]
+name = "stringprep"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ee348cb74b87454fff4b551cbf727025810a004f88aeacae7f85b87f4e9a1c1"
+dependencies = [
+ "unicode-bidi",
+ "unicode-normalization",
+]
+
+[[package]]
name = "strsim"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -976,9 +2078,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
[[package]]
name = "syn"
-version = "1.0.72"
+version = "1.0.93"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1e8cdbefb79a9a5a65e0db8b47b723ee907b7c7f8496c76a1770b5c310bab82"
+checksum = "04066589568b72ec65f42d65a1a52436e954b168773148893c020269563decf2"
dependencies = [
"proc-macro2",
"quote",
@@ -986,10 +2088,30 @@ dependencies = [
]
[[package]]
+name = "sync_wrapper"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "20518fe4a4c9acf048008599e464deb21beeae3d3578418951a189c235a7a9a8"
+
+[[package]]
+name = "tempfile"
+version = "3.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4"
+dependencies = [
+ "cfg-if",
+ "fastrand",
+ "libc",
+ "redox_syscall",
+ "remove_dir_all",
+ "winapi",
+]
+
+[[package]]
name = "termcolor"
-version = "1.1.2"
+version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
+checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
dependencies = [
"winapi-util",
]
@@ -1004,34 +2126,94 @@ dependencies = [
]
[[package]]
+name = "thiserror"
+version = "1.0.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a"
+dependencies = [
+ "thiserror-impl",
+]
+
+[[package]]
+name = "thiserror-impl"
+version = "1.0.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "time"
+version = "0.1.43"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438"
+dependencies = [
+ "libc",
+ "winapi",
+]
+
+[[package]]
+name = "time"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c2702e08a7a860f005826c6815dcac101b19b5eb330c27fe4a5928fec1d20ddd"
+dependencies = [
+ "itoa",
+ "libc",
+ "num_threads",
+ "quickcheck",
+ "time-macros",
+]
+
+[[package]]
+name = "time-macros"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42657b1a6f4d817cda8e7a0ace261fe0cc946cf3a80314390b22cc61ae080792"
+
+[[package]]
+name = "tinyvec"
+version = "1.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
+dependencies = [
+ "tinyvec_macros",
+]
+
+[[package]]
+name = "tinyvec_macros"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
+
+[[package]]
name = "tokio"
-version = "0.2.25"
+version = "1.18.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6703a273949a90131b290be1fe7b039d0fc884aa1935860dfcbe056f28cd8092"
+checksum = "4903bf0427cf68dddd5aa6a93220756f8be0c34fcfa9f5e6191e103e15a31395"
dependencies = [
"bytes",
- "fnv",
- "futures-core",
- "iovec",
- "lazy_static",
"libc",
"memchr",
- "mio",
- "mio-named-pipes",
- "mio-uds",
+ "mio 0.8.3",
"num_cpus",
- "pin-project-lite 0.1.12",
+ "once_cell",
+ "parking_lot 0.12.0",
+ "pin-project-lite",
"signal-hook-registry",
- "slab",
+ "socket2 0.4.4",
"tokio-macros",
- "winapi 0.3.9",
+ "winapi",
]
[[package]]
name = "tokio-macros"
-version = "0.2.6"
+version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e44da00bfc73a25f814cd8d7e57a68a5c31b74b3152a0a1d1f590c97ed06265a"
+checksum = "b557f72f448c511a979e2564e55d74e6c4432fc96ff4f6241bc6bded342643b7"
dependencies = [
"proc-macro2",
"quote",
@@ -1039,40 +2221,316 @@ dependencies = [
]
[[package]]
+name = "tokio-rustls"
+version = "0.22.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bc6844de72e57df1980054b38be3a9f4702aba4858be64dd700181a8a6d0e1b6"
+dependencies = [
+ "rustls 0.19.1",
+ "tokio",
+ "webpki 0.21.4",
+]
+
+[[package]]
+name = "tokio-socks"
+version = "0.5.1"
+source = "git+https://github.com/open-trade/tokio-socks#3de8300fbce37e2cdaef042e016aa95058d007cf"
+dependencies = [
+ "bytes",
+ "either",
+ "futures-core",
+ "futures-sink",
+ "futures-util",
+ "pin-project",
+ "thiserror",
+ "tokio",
+ "tokio-util 0.6.9",
+]
+
+[[package]]
+name = "tokio-stream"
+version = "0.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "50145484efff8818b5ccd256697f36863f587da82cf8b409c53adf1e840798e3"
+dependencies = [
+ "futures-core",
+ "pin-project-lite",
+ "tokio",
+]
+
+[[package]]
+name = "tokio-tungstenite"
+version = "0.17.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "06cda1232a49558c46f8a504d5b93101d42c0bf7f911f12a105ba48168f821ae"
+dependencies = [
+ "futures-util",
+ "log",
+ "tokio",
+ "tungstenite",
+]
+
+[[package]]
name = "tokio-util"
-version = "0.3.1"
+version = "0.6.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be8242891f2b6cbef26a2d7e8605133c2c554cd35b3e4948ea892d6d68436499"
+checksum = "9e99e1983e5d376cd8eb4b66604d2e99e79f5bd988c3055891dcd8c9e2604cc0"
dependencies = [
"bytes",
"futures-core",
"futures-io",
"futures-sink",
"log",
- "pin-project-lite 0.1.12",
+ "pin-project-lite",
+ "slab",
+ "tokio",
+]
+
+[[package]]
+name = "tokio-util"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0edfdeb067411dba2044da6d1cb2df793dd35add7888d73c16e3381ded401764"
+dependencies = [
+ "bytes",
+ "futures-core",
+ "futures-sink",
+ "pin-project-lite",
"tokio",
]
[[package]]
name = "toml"
-version = "0.5.8"
+version = "0.5.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa"
+checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7"
dependencies = [
"serde",
]
[[package]]
+name = "tower"
+version = "0.4.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a89fd63ad6adf737582df5db40d286574513c69a11dac5214dc3b5603d6713e"
+dependencies = [
+ "futures-core",
+ "futures-util",
+ "pin-project",
+ "pin-project-lite",
+ "tokio",
+ "tokio-util 0.7.1",
+ "tower-layer",
+ "tower-service",
+ "tracing",
+]
+
+[[package]]
+name = "tower-http"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aba3f3efabf7fb41fae8534fc20a817013dd1c12cb45441efb6c82e6556b4cd8"
+dependencies = [
+ "bitflags",
+ "bytes",
+ "futures-core",
+ "futures-util",
+ "http",
+ "http-body",
+ "http-range-header",
+ "httpdate",
+ "mime",
+ "mime_guess",
+ "percent-encoding",
+ "pin-project-lite",
+ "tokio",
+ "tokio-util 0.7.1",
+ "tower-layer",
+ "tower-service",
+ "tracing",
+]
+
+[[package]]
+name = "tower-http"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7d342c6d58709c0a6d48d48dabbb62d4ef955cf5f0f3bbfd845838e7ae88dbae"
+dependencies = [
+ "bitflags",
+ "bytes",
+ "futures-core",
+ "futures-util",
+ "http",
+ "http-body",
+ "http-range-header",
+ "pin-project-lite",
+ "tower",
+ "tower-layer",
+ "tower-service",
+]
+
+[[package]]
+name = "tower-layer"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "343bc9466d3fe6b0f960ef45960509f84480bf4fd96f92901afe7ff3df9d3a62"
+
+[[package]]
+name = "tower-service"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6"
+
+[[package]]
+name = "tracing"
+version = "0.1.34"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5d0ecdcb44a79f0fe9844f0c4f33a342cbcbb5117de8001e6ba0dc2351327d09"
+dependencies = [
+ "cfg-if",
+ "log",
+ "pin-project-lite",
+ "tracing-attributes",
+ "tracing-core",
+]
+
+[[package]]
+name = "tracing-attributes"
+version = "0.1.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cc6b8ad3567499f98a1db7a752b07a7c8c7c7c34c332ec00effb2b0027974b7c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "tracing-core"
+version = "0.1.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f54c8ca710e81886d498c2fd3331b56c93aa248d49de2222ad2742247c60072f"
+dependencies = [
+ "lazy_static",
+]
+
+[[package]]
+name = "try-lock"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
+
+[[package]]
+name = "tungstenite"
+version = "0.17.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d96a2dea40e7570482f28eb57afbe42d97551905da6a9400acc5c328d24004f5"
+dependencies = [
+ "base64",
+ "byteorder",
+ "bytes",
+ "http",
+ "httparse",
+ "log",
+ "rand",
+ "sha-1",
+ "thiserror",
+ "url",
+ "utf-8",
+]
+
+[[package]]
+name = "typenum"
+version = "1.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"
+
+[[package]]
+name = "unicase"
+version = "2.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
+dependencies = [
+ "version_check",
+]
+
+[[package]]
+name = "unicode-bidi"
+version = "0.3.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992"
+
+[[package]]
+name = "unicode-normalization"
+version = "0.1.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9"
+dependencies = [
+ "tinyvec",
+]
+
+[[package]]
+name = "unicode-segmentation"
+version = "1.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99"
+
+[[package]]
name = "unicode-width"
-version = "0.1.8"
+version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
+checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
[[package]]
name = "unicode-xid"
-version = "0.2.2"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04"
+
+[[package]]
+name = "unicode_categories"
+version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
+checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e"
+
+[[package]]
+name = "untrusted"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
+
+[[package]]
+name = "url"
+version = "2.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c"
+dependencies = [
+ "form_urlencoded",
+ "idna",
+ "matches",
+ "percent-encoding",
+]
+
+[[package]]
+name = "utf-8"
+version = "0.7.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
+
+[[package]]
+name = "uuid"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
+dependencies = [
+ "getrandom",
+]
+
+[[package]]
+name = "vcpkg"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]]
name = "vec_map"
@@ -1082,9 +2540,30 @@ checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
[[package]]
name = "version_check"
-version = "0.9.3"
+version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
+checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
+
+[[package]]
+name = "walkdir"
+version = "2.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56"
+dependencies = [
+ "same-file",
+ "winapi",
+ "winapi-util",
+]
+
+[[package]]
+name = "want"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0"
+dependencies = [
+ "log",
+ "try-lock",
+]
[[package]]
name = "wasi"
@@ -1093,16 +2572,124 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
[[package]]
-name = "whoami"
-version = "0.9.0"
+name = "wasi"
+version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7884773ab69074615cb8f8425d0e53f11710786158704fca70f53e71b0e05504"
+checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
-name = "winapi"
-version = "0.2.8"
+name = "wasm-bindgen"
+version = "0.2.80"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "27370197c907c55e3f1a9fbe26f44e937fe6451368324e009cba39e139dc08ad"
+dependencies = [
+ "cfg-if",
+ "wasm-bindgen-macro",
+]
+
+[[package]]
+name = "wasm-bindgen-backend"
+version = "0.2.80"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "53e04185bfa3a779273da532f5025e33398409573f348985af9a1cbf3774d3f4"
+dependencies = [
+ "bumpalo",
+ "lazy_static",
+ "log",
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-macro"
+version = "0.2.80"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "17cae7ff784d7e83a2fe7611cfe766ecf034111b49deb850a3dc7699c08251f5"
+dependencies = [
+ "quote",
+ "wasm-bindgen-macro-support",
+]
+
+[[package]]
+name = "wasm-bindgen-macro-support"
+version = "0.2.80"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
+checksum = "99ec0dc7a4756fffc231aab1b9f2f578d23cd391390ab27f952ae0c9b3ece20b"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-backend",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-shared"
+version = "0.2.80"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d554b7f530dee5964d9a9468d95c1f8b8acae4f282807e7d27d4b03099a46744"
+
+[[package]]
+name = "web-sys"
+version = "0.3.57"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b17e741662c70c8bd24ac5c5b18de314a2c26c32bf8346ee1e6f53de919c283"
+dependencies = [
+ "js-sys",
+ "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"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd"
+dependencies = [
+ "ring",
+ "untrusted",
+]
+
+[[package]]
+name = "webpki-roots"
+version = "0.21.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aabe153544e473b775453675851ecc86863d2a81d786d741f6b76778f2a48940"
+dependencies = [
+ "webpki 0.21.4",
+]
+
+[[package]]
+name = "which"
+version = "4.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c4fb54e6113b6a8772ee41c3404fb0301ac79604489467e0a9ce1f3e97c24ae"
+dependencies = [
+ "either",
+ "lazy_static",
+ "libc",
+]
+
+[[package]]
+name = "whoami"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "524b58fa5a20a2fb3014dd6358b70e6579692a56ef6fce928834e488f42f65e8"
+dependencies = [
+ "wasm-bindgen",
+ "web-sys",
+]
[[package]]
name = "winapi"
@@ -1115,12 +2702,6 @@ dependencies = [
]
[[package]]
-name = "winapi-build"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
-
-[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1132,7 +2713,7 @@ version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
dependencies = [
- "winapi 0.3.9",
+ "winapi",
]
[[package]]
@@ -1142,38 +2723,77 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
+name = "windows-sys"
+version = "0.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2"
+dependencies = [
+ "windows_aarch64_msvc",
+ "windows_i686_gnu",
+ "windows_i686_msvc",
+ "windows_x86_64_gnu",
+ "windows_x86_64_msvc",
+]
+
+[[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.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6"
+
+[[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.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1"
+
+[[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.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2986deb581c4fe11b621998a5e53361efe6b48a151178d0cd9eeffa4dc6acc9"
dependencies = [
- "winapi 0.3.9",
+ "winapi",
]
[[package]]
-name = "ws2_32-sys"
-version = "0.2.1"
+name = "zeroize"
+version = "1.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
-dependencies = [
- "winapi 0.2.8",
- "winapi-build",
-]
+checksum = "94693807d016b2f2d2e14420eb3bfcca689311ff775dcf113d74ea624b7cdf07"
[[package]]
name = "zstd"
-version = "0.8.1+zstd.1.5.0"
+version = "0.9.2+zstd.1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "357d6bb1bd9c6f6a55a5a15c74d01260b272f724dc60cc829b86ebd2172ac5ef"
+checksum = "2390ea1bf6c038c39674f22d95f0564725fc06034a47129179810b2fc58caa54"
dependencies = [
"zstd-safe",
]
[[package]]
name = "zstd-safe"
-version = "4.1.0+zstd.1.5.0"
+version = "4.1.3+zstd.1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d30375f78e185ca4c91930f42ea2c0162f9aa29737032501f93b79266d985ae7"
+checksum = "e99d81b99fb3c2c2c794e3fe56c305c63d5173a16a46b5850b07c935ffc7db79"
dependencies = [
"libc",
"zstd-sys",
@@ -1181,9 +2801,9 @@ dependencies = [
[[package]]
name = "zstd-sys"
-version = "1.6.0+zstd.1.5.0"
+version = "1.6.2+zstd.1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2141bed8922b427761470e6bbfeff255da94fa20b0bbeab0d9297fcaf71e3aa7"
+checksum = "2daf2f248d9ea44454bfcb2516534e8b8ad2fc91bf818a1885495fc42bc8ac9f"
dependencies = [
"cc",
"libc",
diff --git a/Cargo.toml b/Cargo.toml
index 38ab9de..bbbdb94 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,9 +1,10 @@
[package]
name = "hbbs"
-version = "1.1.4"
-authors = ["open-trade <[email protected]>"]
-edition = "2018"
-build= "build.rs"
+version = "1.1.5"
+authors = ["open-trade <[email protected]>"]
+edition = "2021"
+build = "build.rs"
+default-run = "hbbs"
[[bin]]
name = "hbbr"
@@ -17,22 +18,28 @@ serde_derive = "1.0"
serde = "1.0"
serde_json = "1.0"
lazy_static = "1.4"
-clap = "2.33"
-rust-ini = "0.16"
-minreq = { version = "2.3.1", features = ["punycode"] }
+clap = "2"
+rust-ini = "0.18"
+minreq = { version = "2.4", features = ["punycode"] }
machine-uid = "0.2"
mac_address = "1.1"
-whoami = "0.9"
+whoami = "1.2"
base64 = "0.13"
-cryptoxide = "0.3"
-
-[build-dependencies]
-hbb_common = { path = "libs/hbb_common" }
-
-[workspace]
-members = ["libs/hbb_common"]
-
-[dependencies.rocksdb]
-default-features = false
-features = ["lz4"]
-version = "0.15"
+axum = { version = "0.5", features = ["headers"] }
+sqlx = { git = "https://github.com/open-trade/sqlx", features = [ "runtime-tokio-rustls", "sqlite", "macros", "chrono", "json" ] }
+deadpool = "0.8"
+async-trait = "0.1"
+async-speed-limit = { git = "https://github.com/open-trade/async-speed-limit" }
+uuid = { version = "0.8", features = ["v4"] }
+bcrypt = "0.12"
+chrono = "0.4"
+jsonwebtoken = "8"
+headers = "0.3"
+once_cell = "1.8"
+sodiumoxide = "0.2"
+tokio-tungstenite = "0.17"
+tungstenite = "0.17"
+regex = "1.4"
+tower-http = { version = "0.2", features = ["fs", "trace", "cors"] }
+http = "0.2"
+flexi_logger = { version = "0.22", features = ["async", "use_chrono_for_offset"] }
diff --git a/Dockerfile b/Dockerfile
deleted file mode 100644
index d0b7560..0000000
--- a/Dockerfile
+++ /dev/null
@@ -1,4 +0,0 @@
-FROM ubuntu:20.04
-COPY target/release/hbbs /usr/bin/hbbs
-COPY target/release/hbbr /usr/bin/hbbr
-WORKDIR /root
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..109a903
--- /dev/null
+++ b/README.md
@@ -0,0 +1,23 @@
+# RustDesk Server Program
+
+<<<<<<< HEAD
+Self-host your own RustDesk server, it is free and open source.
+
+```
+cargo build --release
+```
+
+Two executables will be generated in target/release.
+ - hbbs - RustDesk ID/Rendezvous server
+ - hbbr - RustDesk relay server
+
+[**Manual**](https://rustdesk.com/docs/en/self-host/)
+=======
+**Could you please also help finish below "RustDesk Self-Hosting Sever Survey"? So that we can make it better.** https://forms.gle/9sDqAC5JBuB4b52S6
+
+If you are looking for an open source implementation, please go to [rustdesk-server-demo](https://github.com/rustdesk/rustdesk-server-demo).
+
+[Download](https://github.com/rustdesk/rustdesk-server/releases)
+
+[Doc](https://rustdesk.com/docs/en/self-host)
+>>>>>>> 5043b7ce7f5a2230661381cb9c63f84c60414035
diff --git a/db_v2.sqlite3 b/db_v2.sqlite3
new file mode 100644
index 0000000..1985922
--- /dev/null
+++ b/db_v2.sqlite3
Binary files differ
diff --git a/libs/hbb_common b/libs/hbb_common
deleted file mode 160000
-Subproject ec453e5e65bdb3d082cca30416880e4ee0f3665
diff --git a/spk/INFO b/spk/INFO
deleted file mode 100755
index a446791..0000000
--- a/spk/INFO
+++ /dev/null
@@ -1,18 +0,0 @@
-package="RustDesk Server"
-version="1.1.3"
-description="RustDesk is a remote desktop software allowing your own rendezvous/relay server. It attempts to make direct connect via TCP hole punch first, and then forward via relay server if direct connection fails. 4 ports are used. NAT test port: 21115(tcp), ID/rendezvous port: 21116(tcp/udp), relay port: 21117(tcp), Email: (), Key: ()"
-displayname="RustDesk Rendezvous/Relay Server"
-maintainer="CarrieZ Studio"
-maintainer_url="https://rustdesk.com/zh/"
-distributor="RustDesk & 裙下孤魂"
-support_url="https://rustdesk.com/contact/"
-arch="apollolake avoton braswell broadwell broadwellnk bromolow cedarview denverton dockerx64 geminilake grantley kvmx64 purley v1000 x86 x86_64"
-os_min_ver="6.1"
-reloadui="yes"
-startable="yes"
-thirdparty="yes"
-install_reboot="no"
-install_dep_packages=""
-install_conflict_packages=""
-extractsize=""
-checkport="no"
diff --git a/spk/PACKAGE_ICON.PNG b/spk/PACKAGE_ICON.PNG
deleted file mode 100755
index c6c0367..0000000
--- a/spk/PACKAGE_ICON.PNG
+++ /dev/null
Binary files differ
diff --git a/spk/PACKAGE_ICON_256.PNG b/spk/PACKAGE_ICON_256.PNG
deleted file mode 100755
index a80abd5..0000000
--- a/spk/PACKAGE_ICON_256.PNG
+++ /dev/null
Binary files differ
diff --git a/spk/WIZARD_UIFILES/install_uifile b/spk/WIZARD_UIFILES/install_uifile
deleted file mode 100755
index 1da2baa..0000000
--- a/spk/WIZARD_UIFILES/install_uifile
+++ /dev/null
@@ -1,54 +0,0 @@
-[{
- "step_title": "Install Settings",
- "items": [{
- "type": "textfield",
- "desc": "Listening Ports",
- "subitems": [{
- "key": "hbbs_port",
- "desc": "RustDesk ID Server Port",
- "defaultValue": "21116",
- "validator": {
- "allowBlank": false,
- "regex": {
- "expr": "/^([0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$/",
- "errorText": "Digit number only"
- }
- }
- }, {
- "key": "hbbr_port",
- "desc": "RustDesk Relay Server Port",
- "defaultValue": "21117",
- "validator": {
- "allowBlank": false,
- "regex": {
- "expr": "/^([0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$/",
- "errorText": "Digit number only"
- }
- }
- }]
- },{
- "type": "textfield",
- "desc": "Registered email, check http://rustdesk.com/server for more information",
- "subitems": [{
- "key": "email",
- "desc": "Email",
- "validator": {
- "allowBlank": false,
- "regex": {
- "expr": "/^\\w+([-+.']\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$/",
- "errorText": "Invalid email format"
- }
- }
- }]
- },{
- "type": "textfield",
- "desc": "Only allow the client with the same key",
- "subitems": [{
- "key": "key",
- "desc": "Key",
- "validator": {
- "allowBlank": true
- }
- }]
- }]
- }]
diff --git a/spk/scripts/RustDesk_Server.sc b/spk/scripts/RustDesk_Server.sc
deleted file mode 100755
index 37eb1f4..0000000
--- a/spk/scripts/RustDesk_Server.sc
+++ /dev/null
@@ -1,23 +0,0 @@
-[RustDesk_Server_HBBR]
-title="RustDesk Server (HBBR_TCP)"
-desc="RustDesk Server"
-port_forward="yes"
-dst.ports="21117/tcp"
-
-[RustDesk_Server_HBBS_TCP]
-title="RustDesk Server (HBBS_TCP)"
-desc="RustDesk Server"
-port_forward="yes"
-dst.ports="21116/tcp"
-
-[RustDesk_Server_HBBS_UDP]
-title="RustDesk Server (HBBS_UDP)"
-desc="RustDesk Server"
-port_forward="yes"
-dst.ports="21116/udp"
-
-[RustDesk_Server_NAT_TCP]
-title="RustDesk Server (NAT_TCP)"
-desc="RustDesk Server"
-port_forward="yes"
-dst.ports="21115/tcp"
diff --git a/spk/scripts/installer b/spk/scripts/installer
deleted file mode 100755
index 9d6bb71..0000000
--- a/spk/scripts/installer
+++ /dev/null
@@ -1,167 +0,0 @@
-#!/bin/sh
-
-PACKAGE_NAME="$SYNOPKG_PKGNAME"
-PACKAGE_BASE="/var/packages/${PACKAGE_NAME}/target"
-PACKAGE_SSS="/var/packages/${PACKAGE_NAME}/scripts/start-stop-status"
-
-SERVICETOOL="/usr/syno/bin/servicetool"
-GETKEYVALUE="/usr/syno/bin/synogetkeyvalue"
-SETKEYVALUE="/usr/syno/bin/synosetkeyvalue"
-FWFILENAME="RustDesk_Server.sc"
-
-[ "${hbbr_port}" == "" ] && hbbr_port="21117"
-[ "${hbbs_port}" == "" ] && hbbs_port="21116"
-[ "${key}" == "" ] && key=""
-[ "${email}" == "" ] && email=""
-nat_port=`expr ${hbbs_port} - 1`
-
-preinst() {
- exit 0
-}
-
-postinst() {
- if [ "${SYNOPKG_PKG_STATUS}" == "INSTALL" ]; then
- # 导入另一个RustDesk服务器数据
- import_db="false"
- import_all="false"
- if [ "${rds_old_import_all}" == "true" ]; then
- rds_old_import_db="true"
- import_all="true"
- elif [ "${rds_import_all}" == "true" ]; then
- rds_import_db="true"
- import_all="true"
- fi
- if [ "${rds_old_import_db}" == "true" ]; then
- import_db="true"
- PACKAGE_IMPORT_DIR="/var/packages/RustDesk_Server"
- elif [ "${rds_import_db}" == "true" ]; then
- import_db="true"
- PACKAGE_IMPORT_DIR="/var/packages/RustDesk Server"
- fi
- if [ "${import_db}" == "true" ]; then
- [ -x "${PACKAGE_IMPORT_DIR}/scripts/start-stop-status" ] \
- && SYNOPKG_PKGNAME="RustDesk Server" "${PACKAGE_IMPORT_DIR}/scripts/start-stop-status" stop 2>&1
- [ -f "${PACKAGE_IMPORT_DIR}/enabled" ] && rm -f "${PACKAGE_IMPORT_DIR}/enabled"
- [ -d "${PACKAGE_IMPORT_DIR}/target/hbbs.db" ] && cp -prf "${PACKAGE_IMPORT_DIR}/target/hbbs.db" "${PACKAGE_BASE}"
- fi
- if [ "${import_all}" == "true" ]; then
- [ -d "${PACKAGE_IMPORT_DIR}/target/logs" ] && cp -prf "${PACKAGE_IMPORT_DIR}/target/logs" "${PACKAGE_BASE}"
- fi
-
- # 添加应用配置
- sed -i "s/relay port: 21117/relay port: ${hbbr_port}/" "/var/packages/${PACKAGE_NAME}/INFO"
- sed -i "s/ID\/rendezvous port: 21116/ID\/rendezvous port: ${hbbs_port}/" "/var/packages/${PACKAGE_NAME}/INFO"
- sed -i "s/NAT test port: 21115/NAT test port: ${nat_port}/" "/var/packages/${PACKAGE_NAME}/INFO"
- sed -i "s/Key: ()/Key: (${key})/" "/var/packages/${PACKAGE_NAME}/INFO"
- sed -i "s/Email: ()/Email: (${email})/" "/var/packages/${PACKAGE_NAME}/INFO"
- sed -i "s/21117/${hbbr_port}/" "/var/packages/${PACKAGE_NAME}/scripts/${FWFILENAME}"
- sed -i "s/21116/${hbbs_port}/" "/var/packages/${PACKAGE_NAME}/scripts/${FWFILENAME}"
- sed -i "s/21115/${nat_port}/" "/var/packages/${PACKAGE_NAME}/scripts/${FWFILENAME}"
- sed -i "s/port=[^ ]*/port=${hbbr_port}/g" "${PACKAGE_BASE}/config/hbbr.conf"
- sed -i "s/port=[^ ]*/port=${hbbs_port}/g" "${PACKAGE_BASE}/config/hbbs.conf"
- sed -i "s/key=[^ ]*/key=${key}/g" "${PACKAGE_BASE}/config/hbbs.conf"
- sed -i "s/email=[^ ]*/email=${email}/g" "${PACKAGE_BASE}/config/hbbs.conf"
-
- # 添加防火墙配置
- cat "/var/packages/${PACKAGE_NAME}/scripts/${FWFILENAME}" >"/tmp/${FWFILENAME}"
- ${SERVICETOOL} --install-configure-file --package "/tmp/${FWFILENAME}" >/dev/null
- rm -f "/tmp/${FWFILENAME}"
-
- # 设置文件权限
- chmod -R 755 "${PACKAGE_BASE}"/*
- chmod -R 755 "/var/packages/${PACKAGE_NAME}/scripts"/*
- chmod -R 755 "/var/packages/${PACKAGE_NAME}/WIZARD_UIFILES"/*
- chmod 644 "/var/packages/${PACKAGE_NAME}/INFO"
- fi
-
- exit 0
-}
-
-preuninst() {
- # 停用套件
- "${PACKAGE_SSS}" stop
-
- # 删除防火墙配置
- if [ "${SYNOPKG_PKG_STATUS}" == "UNINSTALL" ]; then
- ${SERVICETOOL} --remove-configure-file --package "${FWFILENAME}" >/dev/null
- fi
-
- exit 0
-}
-
-postuninst() {
- # 删除不必要的目录...
- if [ -d "/usr/syno/etc/packages/${PACKAGE_NAME}" ]; then
- rm -rf "/usr/syno/etc/packages/${PACKAGE_NAME}"
- fi
-
- exit 0
-}
-
-preupgrade() {
- # 停用套件
- "${PACKAGE_SSS}" stop
-
-# Not working yet...
-# # 检索旧设置...
-# hbbr_port=`${GETKEYVALUE} "${PACKAGE_BASE}/config/hbbr.conf" port`
-# hbbs_port=`${GETKEYVALUE} "${PACKAGE_BASE}/config/hbbs.conf" port`
-# sed -i "s/21117/${hbbr_port}/" "/var/packages/${PACKAGE_NAME}/WIZARD_UIFILES/upgrade_uifile"
-# sed -i "s/21116/${hbbs_port}/" "/var/packages/${PACKAGE_NAME}/WIZARD_UIFILES/upgrade_uifile"
-## Not working yet...
-
- # 备份数据文件...
- if [ -d "${SYNOPKG_PKGDEST}" ]; then
- DIRS4BACKUP="data logs hbbs.db config"
- for DIR in $DIRS4BACKUP; do
- if [ -d "${SYNOPKG_PKGDEST}/${DIR}" ]; then
- mkdir -p "${SYNOPKG_PKGDEST}/../${PACKAGE_NAME}_upgrade/${DIR}"
- mv "${SYNOPKG_PKGDEST}/${DIR}"/* "${SYNOPKG_PKGDEST}/../${PACKAGE_NAME}_upgrade/${DIR}"
- rmdir "${SYNOPKG_PKGDEST}/${DIR}"
- elif [ -f "${SYNOPKG_PKGDEST}/${DIR}" ]; then
- mv "${SYNOPKG_PKGDEST}/${DIR}" "${SYNOPKG_PKGDEST}/../${PACKAGE_NAME}_upgrade"
- fi
- done
- fi
-
- exit 0
-}
-
-postupgrade() {
- # 恢复数据文件...
- if [ -d "${SYNOPKG_PKGDEST}/../${PACKAGE_NAME}_upgrade" ]; then
- for DIR in `ls "${SYNOPKG_PKGDEST}/../${PACKAGE_NAME}_upgrade"`
- do
- if [ -d "${SYNOPKG_PKGDEST}/../${PACKAGE_NAME}_upgrade/${DIR}" ]; then
- [ ! -d "${SYNOPKG_PKGDEST}/${DIR}" ] && mkdir "${SYNOPKG_PKGDEST}/${DIR}"
- mv "${SYNOPKG_PKGDEST}/../${PACKAGE_NAME}_upgrade/${DIR}"/* "${SYNOPKG_PKGDEST}/${DIR}"
- rmdir "${SYNOPKG_PKGDEST}/../${PACKAGE_NAME}_upgrade/${DIR}"
- elif [ -f "${SYNOPKG_PKGDEST}/../${PACKAGE_NAME}_upgrade/${DIR}" ]; then
- mv "${SYNOPKG_PKGDEST}/../${PACKAGE_NAME}_upgrade/${DIR}" "${SYNOPKG_PKGDEST}"
- fi
- done
- rmdir "${SYNOPKG_PKGDEST}/../${PACKAGE_NAME}_upgrade"
- fi
-
- # 恢复设置...
- hbbr_port=`${GETKEYVALUE} "${PACKAGE_BASE}/config/hbbr.conf" port` >>/tmp/wakko.txt
- hbbs_port=`${GETKEYVALUE} "${PACKAGE_BASE}/config/hbbs.conf" port` >>/tmp/wakko.txt
- nat_port=`expr ${hbbs_port} - 1`
- key=`${GETKEYVALUE} "${PACKAGE_BASE}/config/hbbs.conf" key` >>/tmp/wakko.txt
- email=`${GETKEYVALUE} "${PACKAGE_BASE}/config/hbbs.conf" email` >>/tmp/wakko.txt
- sed -i "s/relay port: 21117/relay port: ${hbbr_port}/" "/var/packages/${PACKAGE_NAME}/INFO" >>/tmp/wakko.txt
- sed -i "s/ID\/rendezvous port: 21116/ID\/rendezvous port: ${hbbs_port}/" "/var/packages/${PACKAGE_NAME}/INFO" >>/tmp/wakko.txt
- sed -i "s/NAT test port: 21115/NAT test port: ${nat_port}/" "/var/packages/${PACKAGE_NAME}/INFO" >>/tmp/wakko.txt
- sed -i "s/Key: ()/Key: (${key})/" "/var/packages/${PACKAGE_NAME}/INFO"
- sed -i "s/Email: ()/Email: (${email})/" "/var/packages/${PACKAGE_NAME}/INFO"
- sed -i "s/21117/${hbbr_port}/" "/var/packages/${PACKAGE_NAME}/scripts/${FWFILENAME}" >>/tmp/wakko.txt
- sed -i "s/21116/${hbbs_port}/" "/var/packages/${PACKAGE_NAME}/scripts/${FWFILENAME}" >>/tmp/wakko.txt
- sed -i "s/21115/${nat_port}/" "/var/packages/${PACKAGE_NAME}/scripts/${FWFILENAME}" >>/tmp/wakko.txt
-
- # 设置文件权限
- chmod -R 755 "/var/packages/${PACKAGE_NAME}/scripts"/*
- chmod -R 755 "/var/packages/${PACKAGE_NAME}/WIZARD_UIFILES"/*
- chmod 644 "/var/packages/${PACKAGE_NAME}/INFO"
-
- exit 0
-}
diff --git a/spk/scripts/postinst b/spk/scripts/postinst
deleted file mode 100755
index f6c4bd9..0000000
--- a/spk/scripts/postinst
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-. "`dirname \"$0\"`/installer"
-`basename "$0"` >$SYNOPKG_TEMP_LOGFILE
diff --git a/spk/scripts/postuninst b/spk/scripts/postuninst
deleted file mode 100755
index f6c4bd9..0000000
--- a/spk/scripts/postuninst
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-. "`dirname \"$0\"`/installer"
-`basename "$0"` >$SYNOPKG_TEMP_LOGFILE
diff --git a/spk/scripts/postupgrade b/spk/scripts/postupgrade
deleted file mode 100755
index f6c4bd9..0000000
--- a/spk/scripts/postupgrade
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-. "`dirname \"$0\"`/installer"
-`basename "$0"` >$SYNOPKG_TEMP_LOGFILE
diff --git a/spk/scripts/preinst b/spk/scripts/preinst
deleted file mode 100755
index f6c4bd9..0000000
--- a/spk/scripts/preinst
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-. "`dirname \"$0\"`/installer"
-`basename "$0"` >$SYNOPKG_TEMP_LOGFILE
diff --git a/spk/scripts/preuninst b/spk/scripts/preuninst
deleted file mode 100755
index f6c4bd9..0000000
--- a/spk/scripts/preuninst
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-. "`dirname \"$0\"`/installer"
-`basename "$0"` >$SYNOPKG_TEMP_LOGFILE
diff --git a/spk/scripts/preupgrade b/spk/scripts/preupgrade
deleted file mode 100755
index f6c4bd9..0000000
--- a/spk/scripts/preupgrade
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-. "`dirname \"$0\"`/installer"
-`basename "$0"` >$SYNOPKG_TEMP_LOGFILE
diff --git a/spk/scripts/start-stop-status b/spk/scripts/start-stop-status
deleted file mode 100755
index 4af2f36..0000000
--- a/spk/scripts/start-stop-status
+++ /dev/null
@@ -1,158 +0,0 @@
-#!/bin/sh
-
-
-sError="ERROR: "
-[ ! -z "$SYNOPKG_PKGNAME" ] && sError="<br />${sError}"
-TIMEOUT=120
-PACKAGE_NAME="RustDesk Server"
-PACKAGE_BASE="/var/packages/${PACKAGE_NAME}/target"
-HBBR_BIN="${PACKAGE_BASE}/bin/hbbr"
-HBBR_PORT=`synogetkeyvalue "${PACKAGE_BASE}/config/hbbr.conf" port`
-HBBR_LOG="/var/log/hbbr.log"
-HBBS_BIN="${PACKAGE_BASE}/bin/hbbs"
-HBBS_PORT=`synogetkeyvalue "${PACKAGE_BASE}/config/hbbs.conf" port`
-KEY=`synogetkeyvalue "${PACKAGE_BASE}/config/hbbs.conf" key`
-EMAIL=`synogetkeyvalue "${PACKAGE_BASE}/config/hbbs.conf" email`
-HBBS_LOG="/var/log/hbbs.log"
-PACKAGE_ENABLED="/var/packages/${PACKAGE_NAME}/enabled"
-PS_CMD="/bin/ps -w"
-DSM_MAJORVERSION=`synogetkeyvalue /etc.defaults/VERSION majorversion`
-if [[ $DSM_MAJORVERSION -gt 5 ]]; then
- PS_CMD="$PS_CMD -x"
-fi
-
-CheckIfDaemonAlive() {
- local PID="$1"
- PROCESS_ALIVE="0"
- [ -z "$PID" ] && return 1
-
- kill -0 "$PID"
- [ "0" == "$?" ] && PROCESS_ALIVE="1"
-}
-
-running_hbbr() {
- local PID=$(${PS_CMD} | sed -e 's/^[ \t]*//' | grep -v grep | grep hbbr | grep "${PACKAGE_NAME}" | head -n1 | cut -f1 -d' ')
- CheckIfDaemonAlive $PID
- [ "0" == "$PROCESS_ALIVE" ] && return 1
- return 0
-}
-
-running_hbbs() {
- local PID=$(${PS_CMD} | sed -e 's/^[ \t]*//' | grep -v grep | grep hbbs | grep "${PACKAGE_NAME}" | head -n1 | cut -f1 -d' ')
- CheckIfDaemonAlive $PID
- [ "0" == "$PROCESS_ALIVE" ] && return 1
- return 0
-}
-
-start() {
- [ "$SYNOPKG_TEMP_LOGFILE" == "" ] && SYNOPKG_TEMP_LOGFILE="/var/log/rustdeskserver.start.log"
- LANG=C cd "$PACKAGE_BASE" && (nohup "$HBBR_BIN" -p $HBBR_PORT -k "$KEY" -m "$EMAIL" > "$HBBR_LOG" 2>&1 &) && (nohup "$HBBS_BIN" -p $HBBS_PORT -k "$KEY" -m "$EMAIL" > "$HBBS_LOG" 2>&1 &)
-
-
- i=0
- while true; do
- if ! running_hbbr || ! running_hbbs ; then
-# echo "WAIT: ${i}s of ${TIMEOUT}s"
- sleep 5s
- i=$((i+5))
- else
- break
- fi
- [ $i -ge $TIMEOUT ] && break
- done
-
- # 检查hbbr进程状态
- if ! running_hbbr ; then
- echo -e "${sError}hbbr process not running" | tee -a $SYNOPKG_TEMP_LOGFILE
- stop
- return 1
- fi
-
- # 检查hbbs进程状态
- if ! running_hbbs ; then
- echo -e "${sError}hbbs process not running" | tee -a $SYNOPKG_TEMP_LOGFILE
- stop
- return 1
- fi
-
- return 0
-}
-
-stop() {
- [ "$SYNOPKG_TEMP_LOGFILE" == "" ] && SYNOPKG_TEMP_LOGFILE="/var/log/rustdeskserver.stop.log"
- # 检查hbbr进程状态
- if running_hbbr ; then
- local PID=$(${PS_CMD} | sed -e 's/^[ \t]*//' | grep -v grep | grep hbbr | grep "${PACKAGE_NAME}" | head -n1 | cut -f1 -d' ')
- [ -z "$PID" ] && return 0
- kill -15 $PID
- sleep 5s
-
- # 检查hbbr进程状态
- if running_hbbr ; then
- kill -9 $PID
- sleep 5s
- if running_hbbr ; then
- echo "${sError}Failed to kill hbbr process(pid=$PID)!" | tee -a $SYNOPKG_TEMP_LOGFILE
- return 1
- fi
- fi
- fi
-
- # 检查hbbs进程状态
- if running_hbbs ; then
- local PID=$(${PS_CMD} | sed -e 's/^[ \t]*//' | grep -v grep | grep hbbs | grep "${PACKAGE_NAME}" | head -n1 | cut -f1 -d' ')
- [ -z "$PID" ] && return 0
- kill -15 $PID
- sleep 5s
-
- # 检查hbbs进程状态
- if running_hbbs ; then
- kill -9 $PID
- sleep 5s
- if running_hbbs ; then
- echo "${sError}无法关闭hbbs进程 (pid=$PID)!" | tee -a $SYNOPKG_TEMP_LOGFILE
- return 1
- fi
- fi
- fi
-
- return 0
-}
-
-case $1 in
- start)
- # 启动服务器
- start
- exit $?
- ;;
- stop)
- # 关闭服务器
- stop
- exit $?
- ;;
- status)
- # 检查套件开关
- if [ ! -f "${PACKAGE_ENABLED}" ]; then
- echo "${sError}package not started" | tee -a $SYNOPKG_TEMP_LOGFILE
- exit 0
- fi
-
- # 检查hbbr进程状态
- if ! running_hbbr ; then
- echo "${sError}hbbr process killed" | tee -a $SYNOPKG_TEMP_LOGFILE
- exit 1
- fi
-
- # 检查hbbs进程状态
- if ! running_hbbs ; then
- echo "${sError}hbbs process killed" | tee -a $SYNOPKG_TEMP_LOGFILE
- exit 1
- fi
-
- exit 0
- ;;
- log)
- echo "$PACKAGE_BASE/logs/server.log"
- exit 0
- ;;
-esac
diff --git a/src/common.rs b/src/common.rs
new file mode 100644
index 0000000..473d730
--- /dev/null
+++ b/src/common.rs
@@ -0,0 +1,128 @@
+use clap::App;
+use hbb_common::{anyhow::Context, log, ResultType};
+use ini::Ini;
+use sodiumoxide::crypto::sign;
+use std::{
+ collections::HashMap,
+ io::prelude::*,
+ io::Read,
+ net::{IpAddr, SocketAddr},
+ time::{Instant, SystemTime},
+};
+
+pub(crate) fn get_expired_time() -> Instant {
+ let now = Instant::now();
+ now.checked_sub(std::time::Duration::from_secs(3600))
+ .unwrap_or(now)
+}
+
+pub(crate) fn test_if_valid_server(host: &str, name: &str) -> ResultType<SocketAddr> {
+ use std::net::ToSocketAddrs;
+ let res = if host.contains(":") {
+ host.to_socket_addrs()?.next().context("")
+ } else {
+ format!("{}:{}", host, 0)
+ .to_socket_addrs()?
+ .next()
+ .context("")
+ };
+ if res.is_err() {
+ log::error!("Invalid {} {}: {:?}", name, host, res);
+ }
+ res
+}
+
+pub(crate) fn get_servers(s: &str, tag: &str) -> Vec<String> {
+ let servers: Vec<String> = s
+ .split(",")
+ .filter(|x| !x.is_empty() && test_if_valid_server(x, tag).is_ok())
+ .map(|x| x.to_owned())
+ .collect();
+ log::info!("{}={:?}", tag, servers);
+ servers
+}
+
+#[inline]
+fn arg_name(name: &str) -> String {
+ name.to_uppercase().replace("_", "-")
+}
+
+pub fn init_args(args: &str, name: &str, about: &str) {
+ let matches = App::new(name)
+ .version(crate::version::VERSION)
+ .author("Purslane Ltd. <[email protected]>")
+ .about(about)
+ .args_from_usage(&args)
+ .get_matches();
+ if let Ok(v) = Ini::load_from_file(".env") {
+ if let Some(section) = v.section(None::<String>) {
+ section
+ .iter()
+ .for_each(|(k, v)| std::env::set_var(arg_name(k), v));
+ }
+ }
+ if let Some(config) = matches.value_of("config") {
+ if let Ok(v) = Ini::load_from_file(config) {
+ if let Some(section) = v.section(None::<String>) {
+ section
+ .iter()
+ .for_each(|(k, v)| std::env::set_var(arg_name(k), v));
+ }
+ }
+ }
+ for (k, v) in matches.args {
+ if let Some(v) = v.vals.get(0) {
+ std::env::set_var(arg_name(k), v.to_string_lossy().to_string());
+ }
+ }
+}
+
+#[inline]
+pub fn get_arg(name: &str) -> String {
+ get_arg_or(name, "".to_owned())
+}
+
+#[inline]
+pub fn get_arg_or(name: &str, default: String) -> String {
+ std::env::var(arg_name(name)).unwrap_or(default)
+}
+
+#[inline]
+pub fn now() -> u64 {
+ SystemTime::now()
+ .duration_since(SystemTime::UNIX_EPOCH)
+ .map(|x| x.as_secs())
+ .unwrap_or_default()
+}
+
+pub fn gen_sk() -> (String, Option<sign::SecretKey>) {
+ let sk_file = "id_ed25519";
+ if let Ok(mut file) = std::fs::File::open(sk_file) {
+ let mut contents = String::new();
+ if file.read_to_string(&mut contents).is_ok() {
+ let sk = base64::decode(&contents).unwrap_or_default();
+ if sk.len() == sign::SECRETKEYBYTES {
+ let mut tmp = [0u8; sign::SECRETKEYBYTES];
+ tmp[..].copy_from_slice(&sk);
+ let pk = base64::encode(&tmp[sign::SECRETKEYBYTES / 2..]);
+ log::info!("Private key comes from {}", sk_file);
+ return (pk, Some(sign::SecretKey(tmp)));
+ }
+ }
+ } else {
+ let (pk, sk) = sign::gen_keypair();
+ let pub_file = format!("{}.pub", sk_file);
+ if let Ok(mut f) = std::fs::File::create(&pub_file) {
+ f.write_all(base64::encode(pk).as_bytes()).ok();
+ if let Ok(mut f) = std::fs::File::create(sk_file) {
+ let s = base64::encode(&sk);
+ if f.write_all(s.as_bytes()).is_ok() {
+ log::info!("Private/public key written to {}/{}", sk_file, pub_file);
+ log::debug!("Public key: {:?}", pk);
+ return (base64::encode(pk), Some(sk));
+ }
+ }
+ }
+ }
+ ("".to_owned(), None)
+}
diff --git a/src/database.rs b/src/database.rs
new file mode 100644
index 0000000..5a199e6
--- /dev/null
+++ b/src/database.rs
@@ -0,0 +1,231 @@
+use async_trait::async_trait;
+use hbb_common::{log, ResultType};
+use serde_json::value::Value;
+use sqlx::{
+ sqlite::SqliteConnectOptions, ConnectOptions, Connection, Error as SqlxError, SqliteConnection,
+};
+use std::{ops::DerefMut, str::FromStr};
+//use sqlx::postgres::PgPoolOptions;
+//use sqlx::mysql::MySqlPoolOptions;
+
+pub(crate) type DB = sqlx::Sqlite;
+pub(crate) type MapValue = serde_json::map::Map<String, Value>;
+pub(crate) type MapStr = std::collections::HashMap<String, String>;
+type Pool = deadpool::managed::Pool<DbPool>;
+
+pub struct DbPool {
+ url: String,
+}
+
+#[async_trait]
+impl deadpool::managed::Manager for DbPool {
+ type Type = SqliteConnection;
+ type Error = SqlxError;
+ async fn create(&self) -> Result<SqliteConnection, SqlxError> {
+ let mut opt = SqliteConnectOptions::from_str(&self.url).unwrap();
+ opt.log_statements(log::LevelFilter::Debug);
+ SqliteConnection::connect_with(&opt).await
+ }
+ async fn recycle(
+ &self,
+ obj: &mut SqliteConnection,
+ ) -> deadpool::managed::RecycleResult<SqlxError> {
+ Ok(obj.ping().await?)
+ }
+}
+
+#[derive(Clone)]
+pub struct Database {
+ pool: Pool,
+}
+
+#[derive(Default)]
+pub struct Peer {
+ pub guid: Vec<u8>,
+ pub id: String,
+ pub uuid: Vec<u8>,
+ pub pk: Vec<u8>,
+ pub user: Option<Vec<u8>>,
+ pub info: String,
+ pub status: Option<i64>,
+}
+
+impl Database {
+ pub async fn new(url: &str) -> ResultType<Database> {
+ if !std::path::Path::new(url).exists() {
+ std::fs::File::create(url).ok();
+ }
+ let n: usize = std::env::var("MAX_CONNECTIONS")
+ .unwrap_or("1".to_owned())
+ .parse()
+ .unwrap_or(1);
+ log::info!("MAX_CONNECTIONS={}", n);
+ let pool = Pool::new(
+ DbPool {
+ url: url.to_owned(),
+ },
+ n,
+ );
+ let _ = pool.get().await?; // test
+ let db = Database { pool };
+ db.create_tables().await?;
+ Ok(db)
+ }
+
+ async fn create_tables(&self) -> ResultType<()> {
+ sqlx::query!(
+ "
+ create table if not exists peer (
+ guid blob primary key not null,
+ id varchar(100) not null,
+ uuid blob not null,
+ pk blob not null,
+ created_at datetime not null default(current_timestamp),
+ user blob,
+ status tinyint,
+ note varchar(300),
+ info text not null
+ ) without rowid;
+ create unique index if not exists index_peer_id on peer (id);
+ create index if not exists index_peer_user on peer (user);
+ create index if not exists index_peer_created_at on peer (created_at);
+ create index if not exists index_peer_status on peer (status);
+ "
+ )
+ .execute(self.pool.get().await?.deref_mut())
+ .await?;
+ Ok(())
+ }
+
+ pub async fn get_peer(&self, id: &str) -> ResultType<Option<Peer>> {
+ Ok(sqlx::query_as!(
+ Peer,
+ "select guid, id, uuid, pk, user, status, info from peer where id = ?",
+ id
+ )
+ .fetch_optional(self.pool.get().await?.deref_mut())
+ .await?)
+ }
+
+ pub async fn get_peer_id(&self, guid: &[u8]) -> ResultType<Option<String>> {
+ Ok(sqlx::query!("select id from peer where guid = ?", guid)
+ .fetch_optional(self.pool.get().await?.deref_mut())
+ .await?
+ .map(|x| x.id))
+ }
+
+ #[inline]
+ pub async fn get_conn(&self) -> ResultType<deadpool::managed::Object<DbPool>> {
+ Ok(self.pool.get().await?)
+ }
+
+ pub async fn update_peer(&self, payload: MapValue, guid: &[u8]) -> ResultType<()> {
+ let mut conn = self.get_conn().await?;
+ let mut tx = conn.begin().await?;
+ if let Some(v) = payload.get("note") {
+ let v = get_str(v);
+ sqlx::query!("update peer set note = ? where guid = ?", v, guid)
+ .execute(&mut tx)
+ .await?;
+ }
+ tx.commit().await?;
+ Ok(())
+ }
+
+ pub async fn insert_peer(
+ &self,
+ id: &str,
+ uuid: &Vec<u8>,
+ pk: &Vec<u8>,
+ info: &str,
+ ) -> ResultType<Vec<u8>> {
+ let guid = uuid::Uuid::new_v4().as_bytes().to_vec();
+ sqlx::query!(
+ "insert into peer(guid, id, uuid, pk, info) values(?, ?, ?, ?, ?)",
+ guid,
+ id,
+ uuid,
+ pk,
+ info
+ )
+ .execute(self.pool.get().await?.deref_mut())
+ .await?;
+ Ok(guid)
+ }
+
+ pub async fn update_pk(
+ &self,
+ guid: &Vec<u8>,
+ id: &str,
+ pk: &Vec<u8>,
+ info: &str,
+ ) -> ResultType<()> {
+ sqlx::query!(
+ "update peer set id=?, pk=?, info=? where guid=?",
+ id,
+ pk,
+ info,
+ guid
+ )
+ .execute(self.pool.get().await?.deref_mut())
+ .await?;
+ Ok(())
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use hbb_common::tokio;
+ #[test]
+ fn test_insert() {
+ insert();
+ }
+
+ #[tokio::main(flavor = "multi_thread")]
+ async fn insert() {
+ let db = super::Database::new("test.sqlite3").await.unwrap();
+ let mut jobs = vec![];
+ for i in 0..10000 {
+ let cloned = db.clone();
+ let id = i.to_string();
+ let a = tokio::spawn(async move {
+ let empty_vec = Vec::new();
+ cloned
+ .insert_peer(&id, &empty_vec, &empty_vec, "")
+ .await
+ .unwrap();
+ });
+ jobs.push(a);
+ }
+ for i in 0..10000 {
+ let cloned = db.clone();
+ let id = i.to_string();
+ let a = tokio::spawn(async move {
+ cloned.get_peer(&id).await.unwrap();
+ });
+ jobs.push(a);
+ }
+ hbb_common::futures::future::join_all(jobs).await;
+ }
+}
+
+#[inline]
+pub fn guid2str(guid: &Vec<u8>) -> String {
+ let mut bytes = [0u8; 16];
+ bytes[..].copy_from_slice(&guid);
+ uuid::Uuid::from_bytes(bytes).to_string()
+}
+
+pub(crate) fn get_str(v: &Value) -> Option<&str> {
+ match v {
+ Value::String(v) => {
+ let v = v.trim();
+ if v.is_empty() {
+ None
+ } else {
+ Some(v)
+ }
+ }
+ _ => None,
+ }
+}
diff --git a/src/hbbr.rs b/src/hbbr.rs
index 7b795f5..f3cfa7c 100644
--- a/src/hbbr.rs
+++ b/src/hbbr.rs
@@ -1,34 +1,41 @@
use clap::App;
+mod common;
mod relay_server;
-use hbb_common::{env_logger::*, ResultType};
+use flexi_logger::*;
+use hbb_common::{config::RELAY_PORT, ResultType};
use relay_server::*;
-use std::sync::{Arc, Mutex};
-mod lic;
+mod version;
fn main() -> ResultType<()> {
- init_from_env(Env::default().filter_or(DEFAULT_FILTER_ENV, "info"));
+ let _logger = Logger::try_with_env_or_str("info")?
+ .log_to_stdout()
+ .format(opt_format)
+ .write_mode(WriteMode::Async)
+ .start()?;
let args = format!(
"-p, --port=[NUMBER(default={})] 'Sets the listening port'
-k, --key=[KEY] 'Only allow the client with the same key'
- {}
",
- DEFAULT_PORT,
- lic::EMAIL_ARG
+ RELAY_PORT,
);
let matches = App::new("hbbr")
- .version(hbbs::VERSION)
- .author("CarrieZ Studio<[email protected]>")
+ .version(version::VERSION)
+ .author("Purslane Ltd. <[email protected]>")
.about("RustDesk Relay Server")
.args_from_usage(&args)
.get_matches();
- if !lic::check_lic(matches.value_of("email").unwrap_or(""), hbbs::VERSION) {
+ if let Ok(v) = ini::Ini::load_from_file(".env") {
+ if let Some(section) = v.section(None::<String>) {
+ section.iter().for_each(|(k, v)| std::env::set_var(k, v));
+ }
+ }
+ #[cfg(not(debug_assertions))]
+ if !lic::check_lic(matches.value_of("email").unwrap_or(""), version::VERSION) {
return Ok(());
}
- let stop: Arc<Mutex<bool>> = Default::default();
start(
- matches.value_of("port").unwrap_or(DEFAULT_PORT),
+ matches.value_of("port").unwrap_or(&RELAY_PORT.to_string()),
matches.value_of("key").unwrap_or(""),
- stop,
)?;
Ok(())
}
diff --git a/src/lib.rs b/src/lib.rs
index f0fd5b2..8da29a2 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,6 +1,6 @@
mod rendezvous_server;
-mod sled_async;
pub use rendezvous_server::*;
-use sled_async::*;
+pub mod common;
+mod database;
+mod peer;
mod version;
-pub use version::*;
diff --git a/src/lic.rs b/src/lic.rs
deleted file mode 100644
index 171c6b1..0000000
--- a/src/lic.rs
+++ /dev/null
@@ -1,170 +0,0 @@
-use hbb_common::{bail, log, ResultType, rand::{self, Rng}};
-use serde_derive::{Deserialize, Serialize};
-use std::io::prelude::*;
-use std::path::Path;
-
-#[derive(Debug, PartialEq, Default, Serialize, Deserialize, Clone)]
-pub struct Machine {
- #[serde(default)]
- hostname: String,
- #[serde(default)]
- uid: String,
- #[serde(default)]
- mac: String,
-}
-
-#[derive(Debug, PartialEq, Default, Serialize, Deserialize, Clone)]
-pub struct Post {
- #[serde(default)]
- machine: String,
- #[serde(default)]
- email: String,
- #[serde(default)]
- status: String,
- #[serde(default)]
- version: String,
- #[serde(default)]
- next_check_time: u64,
- #[serde(default)]
- nonce: String,
- #[serde(default)]
- tip: String,
-}
-
-const LICENSE_FILE: &'static str = ".license.txt";
-
-pub fn check_lic(email: &str, version: &str) -> bool {
- if email.is_empty() {
- log::error!("Registered email required (-m option). Please pay and register on https://rustdesk.com/server.");
- return false;
- }
-
- let is_docker = std::path::Path::new("/.dockerenv").exists();
- let machine = if is_docker { "".to_owned() } else { get_lic() };
- if !is_docker {
- let path = Path::new(LICENSE_FILE);
- if Path::is_file(&path) {
- let contents = std::fs::read_to_string(&path).unwrap_or("".to_owned());
- if verify(&contents, &machine) {
- async_check_email(&machine, email, version, 0);
- return true;
- }
- }
- }
-
- match check_email(machine.clone(), email.to_owned(), version.to_owned()) {
- Ok(v) => {
- async_check_email(&machine, email, version, v);
- return true;
- }
- Err(err) => {
- log::error!("{}", err);
- return false;
- }
- }
-}
-
-fn async_check_email(machine: &str, email: &str, version: &str, wait: u64) {
- let machine = machine.to_owned();
- let email = email.to_owned();
- let version = version.to_owned();
- std::thread::spawn(move || {
- let mut wait = wait;
- loop {
- let machine = machine.clone();
- let email = email.clone();
- let version = version.clone();
- std::thread::sleep(std::time::Duration::from_secs(wait));
- match check_email(machine, email, version) {
- Ok(v) => {
- wait = v;
- }
- Err(err) => {
- log::error!("{}", err);
- std::process::exit(-1);
- }
- }
- }
- });
-}
-
-fn write_lic(lic: &str) {
- if let Ok(mut f) = std::fs::File::create(LICENSE_FILE) {
- f.write_all(lic.as_bytes()).ok();
- f.sync_all().ok();
- }
-}
-
-fn check_email(machine: String, email: String, version: String) -> ResultType<u64> {
- log::info!("Checking email with the license server ...");
- let mut rng = rand::thread_rng();
- let nonce: usize = rng.gen();
- let nonce = nonce.to_string();
- let resp = minreq::post("http://rustdesk.com/api/check-email")
- .with_body(
- serde_json::to_string(&Post {
- machine: machine.clone(),
- version,
- email,
- nonce: nonce.clone(),
- ..Default::default()
- })
- .unwrap(),
- )
- .send()?;
- if resp.reason_phrase == "OK" {
- let p: Post = serde_json::from_str(&resp.as_str()?)?;
- if !p.status.is_empty() {
- std::fs::remove_file(LICENSE_FILE).ok();
- bail!("{}", p.status);
- }
- if p.nonce.is_empty() {
- bail!("Verification failure: nonce required");
- }
- if !verify(&p.nonce, &nonce) {
- bail!("Verification failure: nonce mismatch");
- }
- if !machine.is_empty() {
- if !verify(&p.machine, &machine) {
- bail!("Verification failure");
- }
- write_lic(&p.machine);
- }
- log::info!("License OK");
- if !p.tip.is_empty() {
- log::info!("{}", p.tip);
- }
- let mut wait = p.next_check_time;
- if wait == 0 {
- wait = 3600 * 24 * 30;
- }
-
- Ok(wait)
- } else {
- bail!("Server error: {}", resp.reason_phrase);
- }
-}
-
-fn get_lic() -> String {
- let hostname = whoami::hostname();
- let uid = machine_uid::get().unwrap_or("".to_owned());
- let mac = if let Ok(Some(ma)) = mac_address::get_mac_address() {
- base64::encode(ma.bytes())
- } else {
- "".to_owned()
- };
- serde_json::to_string(&Machine { hostname, uid, mac }).unwrap()
-}
-
-fn verify(enc_str: &str, msg: &str) -> bool {
- if let Ok(data) = base64::decode(enc_str) {
- let key =
- b"\xf1T\xc0\x1c\xffee\x86,S*\xd9.\x91\xcd\x85\x12:\xec\xa9 \x99:\x8a\xa2S\x1f Yy\x93R";
- cryptoxide::ed25519::verify(msg.as_bytes(), &key[..], &data)
- } else {
- false
- }
-}
-
-pub const EMAIL_ARG: &'static str =
- "-m, --email=[EMAIL] 'Sets your email address registered with RustDesk'";
diff --git a/src/main.rs b/src/main.rs
index 8e488f1..db2bbab 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,15 +1,18 @@
// https://tools.ietf.org/rfc/rfc5128.txt
// https://blog.csdn.net/bytxl/article/details/44344855
-use clap::App;
-use hbb_common::{env_logger::*, log, ResultType};
-use hbbs::*;
-mod lic;
-use ini::Ini;
-use std::sync::{Arc, Mutex};
+use flexi_logger::*;
+use hbb_common::{bail, config::RENDEZVOUS_PORT, ResultType};
+use hbbs::{common::*, *};
+
+const RMEM: usize = 0;
fn main() -> ResultType<()> {
- init_from_env(Env::default().filter_or(DEFAULT_FILTER_ENV, "info"));
+ let _logger = Logger::try_with_env_or_str("info")?
+ .log_to_stdout()
+ .format(opt_format)
+ .write_mode(WriteMode::Async)
+ .start()?;
let args = format!(
"-c --config=[FILE] +takes_value 'Sets a custom config file'
-p, --port=[NUMBER(default={})] 'Sets the listening port'
@@ -18,66 +21,19 @@ fn main() -> ResultType<()> {
-u, --software-url=[URL] 'Sets download url of RustDesk software of newest version'
-r, --relay-servers=[HOST] 'Sets the default relay servers, seperated by colon'
-C, --change-id=[BOOL(default=Y)] 'Sets if support to change id'
- {}
+ -M, --rmem=[NUMBER(default={})] 'Sets UDP recv buffer size, set system rmem_max first, e.g., sudo sysctl -w net.core.rmem_max=52428800. vi /etc/sysctl.conf, net.core.rmem_max=52428800, sudo sysctl –p'
-k, --key=[KEY] 'Only allow the client with the same key'",
- DEFAULT_PORT,
- lic::EMAIL_ARG
+ RENDEZVOUS_PORT,
+ RMEM,
);
- let matches = App::new("hbbs")
- .version(crate::VERSION)
- .author("CarrieZ Studio<[email protected]>")
- .about("RustDesk ID/Rendezvous Server")
- .args_from_usage(&args)
- .get_matches();
- let mut section = None;
- let conf; // for holding section
- if let Some(config) = matches.value_of("config") {
- if let Ok(v) = Ini::load_from_file(config) {
- conf = v;
- section = conf.section(None::<String>);
- }
- }
- let get_arg = |name: &str, default: &str| -> String {
- if let Some(v) = matches.value_of(name) {
- return v.to_owned();
- } else if let Some(section) = section {
- if let Some(v) = section.get(name) {
- return v.to_owned();
- }
- }
- return default.to_owned();
- };
- if !lic::check_lic(&get_arg("email", ""), crate::VERSION) {
- return Ok(());
+ init_args(&args, "hbbs", "RustDesk ID/Rendezvous Server");
+ let port = get_arg_or("port", RENDEZVOUS_PORT.to_string()).parse::<i32>()?;
+ if port < 3 {
+ bail!("Invalid port");
}
- let port = get_arg("port", DEFAULT_PORT);
- let relay_servers: Vec<String> = get_arg("relay-servers", "")
- .split(",")
- .filter(|x| !x.is_empty() && test_if_valid_server(x, "relay-server").is_ok())
- .map(|x| x.to_owned())
- .collect();
- let serial: i32 = get_arg("serial", "").parse().unwrap_or(0);
- let id_change_support: bool = get_arg("change-id", "Y").to_uppercase() == "Y";
- let rendezvous_servers: Vec<String> = get_arg("rendezvous-servers", "")
- .split(",")
- .filter(|x| !x.is_empty() && test_if_valid_server(x, "rendezvous-server").is_ok())
- .map(|x| x.to_owned())
- .collect();
- let addr = format!("0.0.0.0:{}", port);
- let addr2 = format!("0.0.0.0:{}", port.parse::<i32>().unwrap_or(0) - 1);
- log::info!("serial={}", serial);
- log::info!("rendezvous-servers={:?}", rendezvous_servers);
- let stop: Arc<Mutex<bool>> = Default::default();
- RendezvousServer::start(
- &addr,
- &addr2,
- relay_servers,
- serial,
- rendezvous_servers,
- get_arg("software-url", ""),
- &get_arg("key", ""),
- stop,
- id_change_support,
- )?;
+ let rmem = get_arg("rmem").parse::<usize>().unwrap_or(RMEM);
+ let serial: i32 = get_arg("serial").parse().unwrap_or(0);
+ let id_change_support: bool = get_arg_or("change-id", "Y".to_owned()).to_uppercase() == "Y";
+ RendezvousServer::start(port, serial, &get_arg("key"), id_change_support, rmem)?;
Ok(())
}
diff --git a/src/peer.rs b/src/peer.rs
new file mode 100644
index 0000000..72999b7
--- /dev/null
+++ b/src/peer.rs
@@ -0,0 +1,185 @@
+use crate::common::*;
+use crate::database;
+use hbb_common::{
+ log,
+ rendezvous_proto::*,
+ tokio::sync::{Mutex, RwLock},
+ ResultType,
+};
+use serde_derive::{Deserialize, Serialize};
+use std::{collections::HashMap, collections::HashSet, net::SocketAddr, sync::Arc, time::Instant};
+
+lazy_static::lazy_static! {
+ pub(crate) static ref IP_BLOCKER: Mutex<HashMap<String, ((u32, Instant), (HashSet<String>, Instant))>> = Default::default();
+ pub(crate) static ref USER_STATUS: RwLock<HashMap<Vec<u8>, Arc<(Option<Vec<u8>>, bool)>>> = Default::default();
+ pub(crate) static ref IP_CHANGES: Mutex<HashMap<String, (Instant, HashMap<String, i32>)>> = Default::default();
+}
+pub static IP_CHANGE_DUR: u64 = 180;
+pub static IP_CHANGE_DUR_X2: u64 = IP_CHANGE_DUR * 2;
+pub static DAY_SECONDS: u64 = 3600 * 24;
+pub static IP_BLOCK_DUR: u64 = 60;
+
+#[derive(Debug, Default, Serialize, Deserialize, Clone)]
+pub(crate) struct PeerInfo {
+ #[serde(default)]
+ pub(crate) ip: String,
+}
+
+#[derive(Clone, Debug)]
+pub(crate) struct Peer {
+ pub(crate) socket_addr: SocketAddr,
+ pub(crate) last_reg_time: Instant,
+ pub(crate) guid: Vec<u8>,
+ pub(crate) uuid: Vec<u8>,
+ pub(crate) pk: Vec<u8>,
+ pub(crate) user: Option<Vec<u8>>,
+ pub(crate) info: PeerInfo,
+ pub(crate) disabled: bool,
+ pub(crate) reg_pk: (u32, Instant), // how often register_pk
+}
+
+impl Default for Peer {
+ fn default() -> Self {
+ Self {
+ socket_addr: "0.0.0.0:0".parse().unwrap(),
+ last_reg_time: get_expired_time(),
+ guid: Vec::new(),
+ uuid: Vec::new(),
+ pk: Vec::new(),
+ info: Default::default(),
+ user: None,
+ disabled: false,
+ reg_pk: (0, get_expired_time()),
+ }
+ }
+}
+
+pub(crate) type LockPeer = Arc<RwLock<Peer>>;
+
+#[derive(Clone)]
+pub(crate) struct PeerMap {
+ map: Arc<RwLock<HashMap<String, LockPeer>>>,
+ pub(crate) db: database::Database,
+}
+
+impl PeerMap {
+ pub(crate) async fn new() -> ResultType<Self> {
+ let db = std::env::var("DB_URL").unwrap_or({
+ #[allow(unused_mut)]
+ let mut db = "db_v2.sqlite3".to_owned();
+ #[cfg(all(windows, not(debug_assertions)))]
+ {
+ if let Some(path) = hbb_common::config::Config::icon_path().parent() {
+ db = format!("{}\\{}", path.to_str().unwrap_or("."), db);
+ }
+ }
+ #[cfg(not(windows))]
+ {
+ db = format!("./{}", db);
+ }
+ db
+ });
+ log::info!("DB_URL={}", db);
+ let pm = Self {
+ map: Default::default(),
+ db: database::Database::new(&db).await?,
+ };
+ Ok(pm)
+ }
+
+ #[inline]
+ pub(crate) async fn update_pk(
+ &mut self,
+ id: String,
+ peer: LockPeer,
+ addr: SocketAddr,
+ uuid: Vec<u8>,
+ pk: Vec<u8>,
+ ip: String,
+ ) -> register_pk_response::Result {
+ log::info!("update_pk {} {:?} {:?} {:?}", id, addr, uuid, pk);
+ let (info_str, guid) = {
+ let mut w = peer.write().await;
+ w.socket_addr = addr;
+ w.uuid = uuid.clone();
+ w.pk = pk.clone();
+ w.last_reg_time = Instant::now();
+ w.info.ip = ip;
+ (
+ serde_json::to_string(&w.info).unwrap_or_default(),
+ w.guid.clone(),
+ )
+ };
+ if guid.is_empty() {
+ match self.db.insert_peer(&id, &uuid, &pk, &info_str).await {
+ Err(err) => {
+ log::error!("db.insert_peer failed: {}", err);
+ return register_pk_response::Result::SERVER_ERROR;
+ }
+ Ok(guid) => {
+ peer.write().await.guid = guid;
+ }
+ }
+ } else {
+ if let Err(err) = self.db.update_pk(&guid, &id, &pk, &info_str).await {
+ log::error!("db.update_pk failed: {}", err);
+ return register_pk_response::Result::SERVER_ERROR;
+ }
+ log::info!("pk updated instead of insert");
+ }
+ register_pk_response::Result::OK
+ }
+
+ #[inline]
+ pub(crate) async fn get(&self, id: &str) -> Option<LockPeer> {
+ let p = self.map.read().await.get(id).map(|x| x.clone());
+ if p.is_some() {
+ return p;
+ } else {
+ if let Ok(Some(v)) = self.db.get_peer(id).await {
+ let peer = Peer {
+ guid: v.guid,
+ uuid: v.uuid,
+ pk: v.pk,
+ user: v.user,
+ info: serde_json::from_str::<PeerInfo>(&v.info).unwrap_or_default(),
+ disabled: v.status == Some(0),
+ ..Default::default()
+ };
+ let peer = Arc::new(RwLock::new(peer));
+ self.map.write().await.insert(id.to_owned(), peer.clone());
+ return Some(peer);
+ }
+ }
+ None
+ }
+
+ #[inline]
+ pub(crate) async fn get_or(&self, id: &str) -> LockPeer {
+ if let Some(p) = self.get(id).await {
+ return p;
+ }
+ let mut w = self.map.write().await;
+ if let Some(p) = w.get(id) {
+ return p.clone();
+ }
+ let tmp = LockPeer::default();
+ w.insert(id.to_owned(), tmp.clone());
+ tmp
+ }
+
+ #[inline]
+ pub(crate) async fn get_in_memory(&self, id: &str) -> Option<LockPeer> {
+ self.map.read().await.get(id).map(|x| x.clone())
+ }
+
+ #[inline]
+ pub(crate) async fn is_in_memory(&self, id: &str) -> bool {
+ self.map.read().await.contains_key(id)
+ }
+
+ #[inline]
+ pub(crate) async fn remove(&self, id: &str) {
+ self.map.write().await.remove(id);
+ }
+}
diff --git a/src/protos/message.rs b/src/protos/message.rs
deleted file mode 100644
index 58e186b..0000000
--- a/src/protos/message.rs
+++ /dev/null
@@ -1,930 +0,0 @@
-// This file is generated by rust-protobuf 2.10.2. Do not edit
-// @generated
-
-// https://github.com/rust-lang/rust-clippy/issues/702
-#![allow(unknown_lints)]
-#![allow(clippy::all)]
-
-#![cfg_attr(rustfmt, rustfmt_skip)]
-
-#![allow(box_pointers)]
-#![allow(dead_code)]
-#![allow(missing_docs)]
-#![allow(non_camel_case_types)]
-#![allow(non_snake_case)]
-#![allow(non_upper_case_globals)]
-#![allow(trivial_casts)]
-#![allow(unsafe_code)]
-#![allow(unused_imports)]
-#![allow(unused_results)]
-//! Generated file from `message.proto`
-
-use protobuf::Message as Message_imported_for_functions;
-use protobuf::ProtobufEnum as ProtobufEnum_imported_for_functions;
-
-/// Generated files are compatible only with the same version
-/// of protobuf runtime.
-// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_10_2;
-
-#[derive(PartialEq,Clone,Default)]
-pub struct RegisterPeer {
- // message fields
- pub hbb_addr: ::std::string::String,
- // special fields
- pub unknown_fields: ::protobuf::UnknownFields,
- pub cached_size: ::protobuf::CachedSize,
-}
-
-impl<'a> ::std::default::Default for &'a RegisterPeer {
- fn default() -> &'a RegisterPeer {
- <RegisterPeer as ::protobuf::Message>::default_instance()
- }
-}
-
-impl RegisterPeer {
- pub fn new() -> RegisterPeer {
- ::std::default::Default::default()
- }
-
- // string hbb_addr = 1;
-
-
- pub fn get_hbb_addr(&self) -> &str {
- &self.hbb_addr
- }
- pub fn clear_hbb_addr(&mut self) {
- self.hbb_addr.clear();
- }
-
- // Param is passed by value, moved
- pub fn set_hbb_addr(&mut self, v: ::std::string::String) {
- self.hbb_addr = v;
- }
-
- // Mutable pointer to the field.
- // If field is not initialized, it is initialized with default value first.
- pub fn mut_hbb_addr(&mut self) -> &mut ::std::string::String {
- &mut self.hbb_addr
- }
-
- // Take field
- pub fn take_hbb_addr(&mut self) -> ::std::string::String {
- ::std::mem::replace(&mut self.hbb_addr, ::std::string::String::new())
- }
-}
-
-impl ::protobuf::Message for RegisterPeer {
- fn is_initialized(&self) -> bool {
- true
- }
-
- fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> {
- while !is.eof()? {
- let (field_number, wire_type) = is.read_tag_unpack()?;
- match field_number {
- 1 => {
- ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.hbb_addr)?;
- },
- _ => {
- ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
- },
- };
- }
- ::std::result::Result::Ok(())
- }
-
- // Compute sizes of nested messages
- #[allow(unused_variables)]
- fn compute_size(&self) -> u32 {
- let mut my_size = 0;
- if !self.hbb_addr.is_empty() {
- my_size += ::protobuf::rt::string_size(1, &self.hbb_addr);
- }
- my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
- self.cached_size.set(my_size);
- my_size
- }
-
- fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
- if !self.hbb_addr.is_empty() {
- os.write_string(1, &self.hbb_addr)?;
- }
- os.write_unknown_fields(self.get_unknown_fields())?;
- ::std::result::Result::Ok(())
- }
-
- fn get_cached_size(&self) -> u32 {
- self.cached_size.get()
- }
-
- fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
- &self.unknown_fields
- }
-
- fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
- &mut self.unknown_fields
- }
-
- fn as_any(&self) -> &dyn (::std::any::Any) {
- self as &dyn (::std::any::Any)
- }
- fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) {
- self as &mut dyn (::std::any::Any)
- }
- fn into_any(self: Box<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
- self
- }
-
- fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
- Self::descriptor_static()
- }
-
- fn new() -> RegisterPeer {
- RegisterPeer::new()
- }
-
- fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
- static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy {
- lock: ::protobuf::lazy::ONCE_INIT,
- ptr: 0 as *const ::protobuf::reflect::MessageDescriptor,
- };
- unsafe {
- descriptor.get(|| {
- let mut fields = ::std::vec::Vec::new();
- fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
- "hbb_addr",
- |m: &RegisterPeer| { &m.hbb_addr },
- |m: &mut RegisterPeer| { &mut m.hbb_addr },
- ));
- ::protobuf::reflect::MessageDescriptor::new::<RegisterPeer>(
- "RegisterPeer",
- fields,
- file_descriptor_proto()
- )
- })
- }
- }
-
- fn default_instance() -> &'static RegisterPeer {
- static mut instance: ::protobuf::lazy::Lazy<RegisterPeer> = ::protobuf::lazy::Lazy {
- lock: ::protobuf::lazy::ONCE_INIT,
- ptr: 0 as *const RegisterPeer,
- };
- unsafe {
- instance.get(RegisterPeer::new)
- }
- }
-}
-
-impl ::protobuf::Clear for RegisterPeer {
- fn clear(&mut self) {
- self.hbb_addr.clear();
- self.unknown_fields.clear();
- }
-}
-
-impl ::std::fmt::Debug for RegisterPeer {
- fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
- ::protobuf::text_format::fmt(self, f)
- }
-}
-
-impl ::protobuf::reflect::ProtobufValue for RegisterPeer {
- fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
- ::protobuf::reflect::ProtobufValueRef::Message(self)
- }
-}
-
-#[derive(PartialEq,Clone,Default)]
-pub struct PeekPeer {
- // message fields
- pub hbb_addr: ::std::string::String,
- // special fields
- pub unknown_fields: ::protobuf::UnknownFields,
- pub cached_size: ::protobuf::CachedSize,
-}
-
-impl<'a> ::std::default::Default for &'a PeekPeer {
- fn default() -> &'a PeekPeer {
- <PeekPeer as ::protobuf::Message>::default_instance()
- }
-}
-
-impl PeekPeer {
- pub fn new() -> PeekPeer {
- ::std::default::Default::default()
- }
-
- // string hbb_addr = 1;
-
-
- pub fn get_hbb_addr(&self) -> &str {
- &self.hbb_addr
- }
- pub fn clear_hbb_addr(&mut self) {
- self.hbb_addr.clear();
- }
-
- // Param is passed by value, moved
- pub fn set_hbb_addr(&mut self, v: ::std::string::String) {
- self.hbb_addr = v;
- }
-
- // Mutable pointer to the field.
- // If field is not initialized, it is initialized with default value first.
- pub fn mut_hbb_addr(&mut self) -> &mut ::std::string::String {
- &mut self.hbb_addr
- }
-
- // Take field
- pub fn take_hbb_addr(&mut self) -> ::std::string::String {
- ::std::mem::replace(&mut self.hbb_addr, ::std::string::String::new())
- }
-}
-
-impl ::protobuf::Message for PeekPeer {
- fn is_initialized(&self) -> bool {
- true
- }
-
- fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> {
- while !is.eof()? {
- let (field_number, wire_type) = is.read_tag_unpack()?;
- match field_number {
- 1 => {
- ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.hbb_addr)?;
- },
- _ => {
- ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
- },
- };
- }
- ::std::result::Result::Ok(())
- }
-
- // Compute sizes of nested messages
- #[allow(unused_variables)]
- fn compute_size(&self) -> u32 {
- let mut my_size = 0;
- if !self.hbb_addr.is_empty() {
- my_size += ::protobuf::rt::string_size(1, &self.hbb_addr);
- }
- my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
- self.cached_size.set(my_size);
- my_size
- }
-
- fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
- if !self.hbb_addr.is_empty() {
- os.write_string(1, &self.hbb_addr)?;
- }
- os.write_unknown_fields(self.get_unknown_fields())?;
- ::std::result::Result::Ok(())
- }
-
- fn get_cached_size(&self) -> u32 {
- self.cached_size.get()
- }
-
- fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
- &self.unknown_fields
- }
-
- fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
- &mut self.unknown_fields
- }
-
- fn as_any(&self) -> &dyn (::std::any::Any) {
- self as &dyn (::std::any::Any)
- }
- fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) {
- self as &mut dyn (::std::any::Any)
- }
- fn into_any(self: Box<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
- self
- }
-
- fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
- Self::descriptor_static()
- }
-
- fn new() -> PeekPeer {
- PeekPeer::new()
- }
-
- fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
- static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy {
- lock: ::protobuf::lazy::ONCE_INIT,
- ptr: 0 as *const ::protobuf::reflect::MessageDescriptor,
- };
- unsafe {
- descriptor.get(|| {
- let mut fields = ::std::vec::Vec::new();
- fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
- "hbb_addr",
- |m: &PeekPeer| { &m.hbb_addr },
- |m: &mut PeekPeer| { &mut m.hbb_addr },
- ));
- ::protobuf::reflect::MessageDescriptor::new::<PeekPeer>(
- "PeekPeer",
- fields,
- file_descriptor_proto()
- )
- })
- }
- }
-
- fn default_instance() -> &'static PeekPeer {
- static mut instance: ::protobuf::lazy::Lazy<PeekPeer> = ::protobuf::lazy::Lazy {
- lock: ::protobuf::lazy::ONCE_INIT,
- ptr: 0 as *const PeekPeer,
- };
- unsafe {
- instance.get(PeekPeer::new)
- }
- }
-}
-
-impl ::protobuf::Clear for PeekPeer {
- fn clear(&mut self) {
- self.hbb_addr.clear();
- self.unknown_fields.clear();
- }
-}
-
-impl ::std::fmt::Debug for PeekPeer {
- fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
- ::protobuf::text_format::fmt(self, f)
- }
-}
-
-impl ::protobuf::reflect::ProtobufValue for PeekPeer {
- fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
- ::protobuf::reflect::ProtobufValueRef::Message(self)
- }
-}
-
-#[derive(PartialEq,Clone,Default)]
-pub struct PeekPeerResponse {
- // message fields
- pub socket_addr: ::std::vec::Vec<u8>,
- // special fields
- pub unknown_fields: ::protobuf::UnknownFields,
- pub cached_size: ::protobuf::CachedSize,
-}
-
-impl<'a> ::std::default::Default for &'a PeekPeerResponse {
- fn default() -> &'a PeekPeerResponse {
- <PeekPeerResponse as ::protobuf::Message>::default_instance()
- }
-}
-
-impl PeekPeerResponse {
- pub fn new() -> PeekPeerResponse {
- ::std::default::Default::default()
- }
-
- // bytes socket_addr = 1;
-
-
- pub fn get_socket_addr(&self) -> &[u8] {
- &self.socket_addr
- }
- pub fn clear_socket_addr(&mut self) {
- self.socket_addr.clear();
- }
-
- // Param is passed by value, moved
- pub fn set_socket_addr(&mut self, v: ::std::vec::Vec<u8>) {
- self.socket_addr = v;
- }
-
- // Mutable pointer to the field.
- // If field is not initialized, it is initialized with default value first.
- pub fn mut_socket_addr(&mut self) -> &mut ::std::vec::Vec<u8> {
- &mut self.socket_addr
- }
-
- // Take field
- pub fn take_socket_addr(&mut self) -> ::std::vec::Vec<u8> {
- ::std::mem::replace(&mut self.socket_addr, ::std::vec::Vec::new())
- }
-}
-
-impl ::protobuf::Message for PeekPeerResponse {
- fn is_initialized(&self) -> bool {
- true
- }
-
- fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> {
- while !is.eof()? {
- let (field_number, wire_type) = is.read_tag_unpack()?;
- match field_number {
- 1 => {
- ::protobuf::rt::read_singular_proto3_bytes_into(wire_type, is, &mut self.socket_addr)?;
- },
- _ => {
- ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
- },
- };
- }
- ::std::result::Result::Ok(())
- }
-
- // Compute sizes of nested messages
- #[allow(unused_variables)]
- fn compute_size(&self) -> u32 {
- let mut my_size = 0;
- if !self.socket_addr.is_empty() {
- my_size += ::protobuf::rt::bytes_size(1, &self.socket_addr);
- }
- my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
- self.cached_size.set(my_size);
- my_size
- }
-
- fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
- if !self.socket_addr.is_empty() {
- os.write_bytes(1, &self.socket_addr)?;
- }
- os.write_unknown_fields(self.get_unknown_fields())?;
- ::std::result::Result::Ok(())
- }
-
- fn get_cached_size(&self) -> u32 {
- self.cached_size.get()
- }
-
- fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
- &self.unknown_fields
- }
-
- fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
- &mut self.unknown_fields
- }
-
- fn as_any(&self) -> &dyn (::std::any::Any) {
- self as &dyn (::std::any::Any)
- }
- fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) {
- self as &mut dyn (::std::any::Any)
- }
- fn into_any(self: Box<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
- self
- }
-
- fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
- Self::descriptor_static()
- }
-
- fn new() -> PeekPeerResponse {
- PeekPeerResponse::new()
- }
-
- fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
- static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy {
- lock: ::protobuf::lazy::ONCE_INIT,
- ptr: 0 as *const ::protobuf::reflect::MessageDescriptor,
- };
- unsafe {
- descriptor.get(|| {
- let mut fields = ::std::vec::Vec::new();
- fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
- "socket_addr",
- |m: &PeekPeerResponse| { &m.socket_addr },
- |m: &mut PeekPeerResponse| { &mut m.socket_addr },
- ));
- ::protobuf::reflect::MessageDescriptor::new::<PeekPeerResponse>(
- "PeekPeerResponse",
- fields,
- file_descriptor_proto()
- )
- })
- }
- }
-
- fn default_instance() -> &'static PeekPeerResponse {
- static mut instance: ::protobuf::lazy::Lazy<PeekPeerResponse> = ::protobuf::lazy::Lazy {
- lock: ::protobuf::lazy::ONCE_INIT,
- ptr: 0 as *const PeekPeerResponse,
- };
- unsafe {
- instance.get(PeekPeerResponse::new)
- }
- }
-}
-
-impl ::protobuf::Clear for PeekPeerResponse {
- fn clear(&mut self) {
- self.socket_addr.clear();
- self.unknown_fields.clear();
- }
-}
-
-impl ::std::fmt::Debug for PeekPeerResponse {
- fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
- ::protobuf::text_format::fmt(self, f)
- }
-}
-
-impl ::protobuf::reflect::ProtobufValue for PeekPeerResponse {
- fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
- ::protobuf::reflect::ProtobufValueRef::Message(self)
- }
-}
-
-#[derive(PartialEq,Clone,Default)]
-pub struct Message {
- // message oneof groups
- pub union: ::std::option::Option<Message_oneof_union>,
- // special fields
- pub unknown_fields: ::protobuf::UnknownFields,
- pub cached_size: ::protobuf::CachedSize,
-}
-
-impl<'a> ::std::default::Default for &'a Message {
- fn default() -> &'a Message {
- <Message as ::protobuf::Message>::default_instance()
- }
-}
-
-#[derive(Clone,PartialEq,Debug)]
-pub enum Message_oneof_union {
- register_peer(RegisterPeer),
- peek_peer(PeekPeer),
- peek_peer_response(PeekPeerResponse),
-}
-
-impl Message {
- pub fn new() -> Message {
- ::std::default::Default::default()
- }
-
- // .hbb.RegisterPeer register_peer = 6;
-
-
- pub fn get_register_peer(&self) -> &RegisterPeer {
- match self.union {
- ::std::option::Option::Some(Message_oneof_union::register_peer(ref v)) => v,
- _ => RegisterPeer::default_instance(),
- }
- }
- pub fn clear_register_peer(&mut self) {
- self.union = ::std::option::Option::None;
- }
-
- pub fn has_register_peer(&self) -> bool {
- match self.union {
- ::std::option::Option::Some(Message_oneof_union::register_peer(..)) => true,
- _ => false,
- }
- }
-
- // Param is passed by value, moved
- pub fn set_register_peer(&mut self, v: RegisterPeer) {
- self.union = ::std::option::Option::Some(Message_oneof_union::register_peer(v))
- }
-
- // Mutable pointer to the field.
- pub fn mut_register_peer(&mut self) -> &mut RegisterPeer {
- if let ::std::option::Option::Some(Message_oneof_union::register_peer(_)) = self.union {
- } else {
- self.union = ::std::option::Option::Some(Message_oneof_union::register_peer(RegisterPeer::new()));
- }
- match self.union {
- ::std::option::Option::Some(Message_oneof_union::register_peer(ref mut v)) => v,
- _ => panic!(),
- }
- }
-
- // Take field
- pub fn take_register_peer(&mut self) -> RegisterPeer {
- if self.has_register_peer() {
- match self.union.take() {
- ::std::option::Option::Some(Message_oneof_union::register_peer(v)) => v,
- _ => panic!(),
- }
- } else {
- RegisterPeer::new()
- }
- }
-
- // .hbb.PeekPeer peek_peer = 7;
-
-
- pub fn get_peek_peer(&self) -> &PeekPeer {
- match self.union {
- ::std::option::Option::Some(Message_oneof_union::peek_peer(ref v)) => v,
- _ => PeekPeer::default_instance(),
- }
- }
- pub fn clear_peek_peer(&mut self) {
- self.union = ::std::option::Option::None;
- }
-
- pub fn has_peek_peer(&self) -> bool {
- match self.union {
- ::std::option::Option::Some(Message_oneof_union::peek_peer(..)) => true,
- _ => false,
- }
- }
-
- // Param is passed by value, moved
- pub fn set_peek_peer(&mut self, v: PeekPeer) {
- self.union = ::std::option::Option::Some(Message_oneof_union::peek_peer(v))
- }
-
- // Mutable pointer to the field.
- pub fn mut_peek_peer(&mut self) -> &mut PeekPeer {
- if let ::std::option::Option::Some(Message_oneof_union::peek_peer(_)) = self.union {
- } else {
- self.union = ::std::option::Option::Some(Message_oneof_union::peek_peer(PeekPeer::new()));
- }
- match self.union {
- ::std::option::Option::Some(Message_oneof_union::peek_peer(ref mut v)) => v,
- _ => panic!(),
- }
- }
-
- // Take field
- pub fn take_peek_peer(&mut self) -> PeekPeer {
- if self.has_peek_peer() {
- match self.union.take() {
- ::std::option::Option::Some(Message_oneof_union::peek_peer(v)) => v,
- _ => panic!(),
- }
- } else {
- PeekPeer::new()
- }
- }
-
- // .hbb.PeekPeerResponse peek_peer_response = 8;
-
-
- pub fn get_peek_peer_response(&self) -> &PeekPeerResponse {
- match self.union {
- ::std::option::Option::Some(Message_oneof_union::peek_peer_response(ref v)) => v,
- _ => PeekPeerResponse::default_instance(),
- }
- }
- pub fn clear_peek_peer_response(&mut self) {
- self.union = ::std::option::Option::None;
- }
-
- pub fn has_peek_peer_response(&self) -> bool {
- match self.union {
- ::std::option::Option::Some(Message_oneof_union::peek_peer_response(..)) => true,
- _ => false,
- }
- }
-
- // Param is passed by value, moved
- pub fn set_peek_peer_response(&mut self, v: PeekPeerResponse) {
- self.union = ::std::option::Option::Some(Message_oneof_union::peek_peer_response(v))
- }
-
- // Mutable pointer to the field.
- pub fn mut_peek_peer_response(&mut self) -> &mut PeekPeerResponse {
- if let ::std::option::Option::Some(Message_oneof_union::peek_peer_response(_)) = self.union {
- } else {
- self.union = ::std::option::Option::Some(Message_oneof_union::peek_peer_response(PeekPeerResponse::new()));
- }
- match self.union {
- ::std::option::Option::Some(Message_oneof_union::peek_peer_response(ref mut v)) => v,
- _ => panic!(),
- }
- }
-
- // Take field
- pub fn take_peek_peer_response(&mut self) -> PeekPeerResponse {
- if self.has_peek_peer_response() {
- match self.union.take() {
- ::std::option::Option::Some(Message_oneof_union::peek_peer_response(v)) => v,
- _ => panic!(),
- }
- } else {
- PeekPeerResponse::new()
- }
- }
-}
-
-impl ::protobuf::Message for Message {
- fn is_initialized(&self) -> bool {
- if let Some(Message_oneof_union::register_peer(ref v)) = self.union {
- if !v.is_initialized() {
- return false;
- }
- }
- if let Some(Message_oneof_union::peek_peer(ref v)) = self.union {
- if !v.is_initialized() {
- return false;
- }
- }
- if let Some(Message_oneof_union::peek_peer_response(ref v)) = self.union {
- if !v.is_initialized() {
- return false;
- }
- }
- true
- }
-
- fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> {
- while !is.eof()? {
- let (field_number, wire_type) = is.read_tag_unpack()?;
- match field_number {
- 6 => {
- if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited {
- return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
- }
- self.union = ::std::option::Option::Some(Message_oneof_union::register_peer(is.read_message()?));
- },
- 7 => {
- if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited {
- return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
- }
- self.union = ::std::option::Option::Some(Message_oneof_union::peek_peer(is.read_message()?));
- },
- 8 => {
- if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited {
- return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
- }
- self.union = ::std::option::Option::Some(Message_oneof_union::peek_peer_response(is.read_message()?));
- },
- _ => {
- ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
- },
- };
- }
- ::std::result::Result::Ok(())
- }
-
- // Compute sizes of nested messages
- #[allow(unused_variables)]
- fn compute_size(&self) -> u32 {
- let mut my_size = 0;
- if let ::std::option::Option::Some(ref v) = self.union {
- match v {
- &Message_oneof_union::register_peer(ref v) => {
- let len = v.compute_size();
- my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
- },
- &Message_oneof_union::peek_peer(ref v) => {
- let len = v.compute_size();
- my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
- },
- &Message_oneof_union::peek_peer_response(ref v) => {
- let len = v.compute_size();
- my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
- },
- };
- }
- my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
- self.cached_size.set(my_size);
- my_size
- }
-
- fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
- if let ::std::option::Option::Some(ref v) = self.union {
- match v {
- &Message_oneof_union::register_peer(ref v) => {
- os.write_tag(6, ::protobuf::wire_format::WireTypeLengthDelimited)?;
- os.write_raw_varint32(v.get_cached_size())?;
- v.write_to_with_cached_sizes(os)?;
- },
- &Message_oneof_union::peek_peer(ref v) => {
- os.write_tag(7, ::protobuf::wire_format::WireTypeLengthDelimited)?;
- os.write_raw_varint32(v.get_cached_size())?;
- v.write_to_with_cached_sizes(os)?;
- },
- &Message_oneof_union::peek_peer_response(ref v) => {
- os.write_tag(8, ::protobuf::wire_format::WireTypeLengthDelimited)?;
- os.write_raw_varint32(v.get_cached_size())?;
- v.write_to_with_cached_sizes(os)?;
- },
- };
- }
- os.write_unknown_fields(self.get_unknown_fields())?;
- ::std::result::Result::Ok(())
- }
-
- fn get_cached_size(&self) -> u32 {
- self.cached_size.get()
- }
-
- fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
- &self.unknown_fields
- }
-
- fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
- &mut self.unknown_fields
- }
-
- fn as_any(&self) -> &dyn (::std::any::Any) {
- self as &dyn (::std::any::Any)
- }
- fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) {
- self as &mut dyn (::std::any::Any)
- }
- fn into_any(self: Box<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
- self
- }
-
- fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
- Self::descriptor_static()
- }
-
- fn new() -> Message {
- Message::new()
- }
-
- fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
- static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy {
- lock: ::protobuf::lazy::ONCE_INIT,
- ptr: 0 as *const ::protobuf::reflect::MessageDescriptor,
- };
- unsafe {
- descriptor.get(|| {
- let mut fields = ::std::vec::Vec::new();
- fields.push(::protobuf::reflect::accessor::make_singular_message_accessor::<_, RegisterPeer>(
- "register_peer",
- Message::has_register_peer,
- Message::get_register_peer,
- ));
- fields.push(::protobuf::reflect::accessor::make_singular_message_accessor::<_, PeekPeer>(
- "peek_peer",
- Message::has_peek_peer,
- Message::get_peek_peer,
- ));
- fields.push(::protobuf::reflect::accessor::make_singular_message_accessor::<_, PeekPeerResponse>(
- "peek_peer_response",
- Message::has_peek_peer_response,
- Message::get_peek_peer_response,
- ));
- ::protobuf::reflect::MessageDescriptor::new::<Message>(
- "Message",
- fields,
- file_descriptor_proto()
- )
- })
- }
- }
-
- fn default_instance() -> &'static Message {
- static mut instance: ::protobuf::lazy::Lazy<Message> = ::protobuf::lazy::Lazy {
- lock: ::protobuf::lazy::ONCE_INIT,
- ptr: 0 as *const Message,
- };
- unsafe {
- instance.get(Message::new)
- }
- }
-}
-
-impl ::protobuf::Clear for Message {
- fn clear(&mut self) {
- self.union = ::std::option::Option::None;
- self.union = ::std::option::Option::None;
- self.union = ::std::option::Option::None;
- self.unknown_fields.clear();
- }
-}
-
-impl ::std::fmt::Debug for Message {
- fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
- ::protobuf::text_format::fmt(self, f)
- }
-}
-
-impl ::protobuf::reflect::ProtobufValue for Message {
- fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
- ::protobuf::reflect::ProtobufValueRef::Message(self)
- }
-}
-
-static file_descriptor_proto_data: &'static [u8] = b"\
- \n\rmessage.proto\x12\x03hbb\"$\n\x0cRegisterPeer\x12\x12\n\x08hbb_addr\
- \x18\x01\x20\x01(\tB\0:\0\"\x20\n\x08PeekPeer\x12\x12\n\x08hbb_addr\x18\
- \x01\x20\x01(\tB\0:\0\"+\n\x10PeekPeerResponse\x12\x15\n\x0bsocket_addr\
- \x18\x01\x20\x01(\x0cB\0:\0\"\x9f\x01\n\x07Message\x12,\n\rregister_peer\
- \x18\x06\x20\x01(\x0b2\x11.hbb.RegisterPeerH\0B\0\x12$\n\tpeek_peer\x18\
- \x07\x20\x01(\x0b2\r.hbb.PeekPeerH\0B\0\x125\n\x12peek_peer_response\x18\
- \x08\x20\x01(\x0b2\x15.hbb.PeekPeerResponseH\0B\0B\x07\n\x05union:\0B\0b\
- \x06proto3\
-";
-
-static mut file_descriptor_proto_lazy: ::protobuf::lazy::Lazy<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::lazy::Lazy {
- lock: ::protobuf::lazy::ONCE_INIT,
- ptr: 0 as *const ::protobuf::descriptor::FileDescriptorProto,
-};
-
-fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto {
- ::protobuf::parse_from_bytes(file_descriptor_proto_data).unwrap()
-}
-
-pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto {
- unsafe {
- file_descriptor_proto_lazy.get(|| {
- parse_descriptor_proto()
- })
- }
-}
diff --git a/src/relay_server.rs b/src/relay_server.rs
index 785e875..9eccfe1 100644
--- a/src/relay_server.rs
+++ b/src/relay_server.rs
@@ -1,114 +1,638 @@
+use async_speed_limit::Limiter;
+use async_trait::async_trait;
use hbb_common::{
+ allow_err, bail,
+ bytes::{Bytes, BytesMut},
+ futures_util::{sink::SinkExt, stream::StreamExt},
log,
protobuf::Message as _,
rendezvous_proto::*,
sleep,
tcp::{new_listener, FramedStream},
+ timeout,
tokio::{
self,
- net::TcpListener,
+ io::{AsyncReadExt, AsyncWriteExt},
+ net::{TcpListener, TcpStream},
+ sync::{Mutex, RwLock},
time::{interval, Duration},
},
ResultType,
};
+use sodiumoxide::crypto::sign;
use std::{
- collections::HashMap,
+ collections::{HashMap, HashSet},
+ io::prelude::*,
+ io::Error,
net::SocketAddr,
- sync::{Arc, Mutex},
};
+type Usage = (usize, usize, usize, usize);
+
lazy_static::lazy_static! {
- static ref PEERS: Arc<Mutex<HashMap<String, FramedStream>>> = Arc::new(Mutex::new(HashMap::new()));
+ static ref PEERS: Mutex<HashMap<String, Box<dyn StreamTrait>>> = Default::default();
+ static ref USAGE: RwLock<HashMap<String, Usage>> = Default::default();
+ static ref BLACKLIST: RwLock<HashSet<String>> = Default::default();
+ static ref BLOCKLIST: RwLock<HashSet<String>> = Default::default();
}
-pub const DEFAULT_PORT: &'static str = "21117";
+static mut DOWNGRADE_THRESHOLD: f64 = 0.66;
+static mut DOWNGRADE_START_CHECK: usize = 1800_000; // in ms
+static mut LIMIT_SPEED: usize = 4 * 1024 * 1024; // in bit/s
+static mut TOTAL_BANDWIDTH: usize = 1024 * 1024 * 1024; // in bit/s
+static mut SINGLE_BANDWIDTH: usize = 16 * 1024 * 1024; // in bit/s
+const BLACKLIST_FILE: &'static str = "blacklist.txt";
+const BLOCKLIST_FILE: &'static str = "blocklist.txt";
-#[tokio::main(basic_scheduler)]
-pub async fn start(port: &str, key: &str, stop: Arc<Mutex<bool>>) -> ResultType<()> {
- if !key.is_empty() {
- log::info!("Key: {}", key);
+#[tokio::main(flavor = "multi_thread")]
+pub async fn start(port: &str, key: &str) -> ResultType<()> {
+ let key = get_server_sk(key);
+ if let Ok(mut file) = std::fs::File::open(BLACKLIST_FILE) {
+ let mut contents = String::new();
+ if file.read_to_string(&mut contents).is_ok() {
+ for x in contents.split("\n") {
+ if let Some(ip) = x.trim().split(' ').nth(0) {
+ BLACKLIST.write().await.insert(ip.to_owned());
+ }
+ }
+ }
+ }
+ log::info!(
+ "#blacklist({}): {}",
+ BLACKLIST_FILE,
+ BLACKLIST.read().await.len()
+ );
+ if let Ok(mut file) = std::fs::File::open(BLOCKLIST_FILE) {
+ let mut contents = String::new();
+ if file.read_to_string(&mut contents).is_ok() {
+ for x in contents.split("\n") {
+ if let Some(ip) = x.trim().split(' ').nth(0) {
+ BLOCKLIST.write().await.insert(ip.to_owned());
+ }
+ }
+ }
}
+ log::info!(
+ "#blocklist({}): {}",
+ BLOCKLIST_FILE,
+ BLOCKLIST.read().await.len()
+ );
let addr = format!("0.0.0.0:{}", port);
log::info!("Listening on tcp {}", addr);
- let mut listener = new_listener(addr, false).await?;
+ let addr2 = format!("0.0.0.0:{}", port.parse::<u16>().unwrap() + 2);
+ log::info!("Listening on websocket {}", addr2);
loop {
- if *stop.lock().unwrap() {
- sleep(0.1).await;
- continue;
- }
log::info!("Start");
- io_loop(&mut listener, key, stop.clone()).await;
+ io_loop(
+ new_listener(&addr, false).await?,
+ new_listener(&addr2, false).await?,
+ &key,
+ )
+ .await;
}
}
-async fn io_loop(listener: &mut TcpListener, key: &str, stop: Arc<Mutex<bool>>) {
- let mut timer = interval(Duration::from_millis(100));
+fn check_params() {
+ let tmp = std::env::var("DOWNGRADE_THRESHOLD")
+ .map(|x| x.parse::<f64>().unwrap_or(0.))
+ .unwrap_or(0.);
+ if tmp > 0. {
+ unsafe {
+ DOWNGRADE_THRESHOLD = tmp;
+ }
+ }
+ unsafe { log::info!("DOWNGRADE_THRESHOLD: {}", DOWNGRADE_THRESHOLD) };
+ let tmp = std::env::var("DOWNGRADE_START_CHECK")
+ .map(|x| x.parse::<usize>().unwrap_or(0))
+ .unwrap_or(0);
+ if tmp > 0 {
+ unsafe {
+ DOWNGRADE_START_CHECK = tmp * 1000;
+ }
+ }
+ unsafe { log::info!("DOWNGRADE_START_CHECK: {}s", DOWNGRADE_START_CHECK / 1000) };
+ let tmp = std::env::var("LIMIT_SPEED")
+ .map(|x| x.parse::<f64>().unwrap_or(0.))
+ .unwrap_or(0.);
+ if tmp > 0. {
+ unsafe {
+ LIMIT_SPEED = (tmp * 1024. * 1024.) as usize;
+ }
+ }
+ unsafe { log::info!("LIMIT_SPEED: {}Mb/s", LIMIT_SPEED as f64 / 1024. / 1024.) };
+ let tmp = std::env::var("TOTAL_BANDWIDTH")
+ .map(|x| x.parse::<f64>().unwrap_or(0.))
+ .unwrap_or(0.);
+ if tmp > 0. {
+ unsafe {
+ TOTAL_BANDWIDTH = (tmp * 1024. * 1024.) as usize;
+ }
+ }
+ unsafe {
+ log::info!(
+ "TOTAL_BANDWIDTH: {}Mb/s",
+ TOTAL_BANDWIDTH as f64 / 1024. / 1024.
+ )
+ };
+ let tmp = std::env::var("SINGLE_BANDWIDTH")
+ .map(|x| x.parse::<f64>().unwrap_or(0.))
+ .unwrap_or(0.);
+ if tmp > 0. {
+ unsafe {
+ SINGLE_BANDWIDTH = (tmp * 1024. * 1024.) as usize;
+ }
+ }
+ unsafe {
+ log::info!(
+ "SINGLE_BANDWIDTH: {}Mb/s",
+ SINGLE_BANDWIDTH as f64 / 1024. / 1024.
+ )
+ };
+}
+
+async fn check_cmd(cmd: &str, limiter: Limiter) -> String {
+ let mut res = "".to_owned();
+ let mut fds = cmd.trim().split(" ");
+ match fds.next() {
+ Some("h") => {
+ res = format!(
+ "{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n",
+ "blacklist-add(ba) <ip>",
+ "blacklist-remove(br) <ip>",
+ "blacklist(b) <ip>",
+ "blocklist-add(Ba) <ip>",
+ "blocklist-remove(Br) <ip>",
+ "blocklist(B) <ip>",
+ "downgrade-threshold(dt) [value]",
+ "downgrade-start-check(t) [value(second)]",
+ "limit-speed(ls) [value(Mb/s)]",
+ "total-bandwidth(tb) [value(Mb/s)]",
+ "single-bandwidth(sb) [value(Mb/s)]",
+ "usage(u)"
+ )
+ }
+ Some("blacklist-add" | "ba") => {
+ if let Some(ip) = fds.next() {
+ for ip in ip.split("|") {
+ BLACKLIST.write().await.insert(ip.to_owned());
+ }
+ }
+ }
+ Some("blacklist-remove" | "br") => {
+ if let Some(ip) = fds.next() {
+ if ip == "all" {
+ BLACKLIST.write().await.clear();
+ } else {
+ for ip in ip.split("|") {
+ BLACKLIST.write().await.remove(ip);
+ }
+ }
+ }
+ }
+ Some("blacklist" | "b") => {
+ if let Some(ip) = fds.next() {
+ res = format!("{}\n", BLACKLIST.read().await.get(ip).is_some());
+ } else {
+ for ip in BLACKLIST.read().await.clone().into_iter() {
+ res += &format!("{}\n", ip);
+ }
+ }
+ }
+ Some("blocklist-add" | "Ba") => {
+ if let Some(ip) = fds.next() {
+ for ip in ip.split("|") {
+ BLOCKLIST.write().await.insert(ip.to_owned());
+ }
+ }
+ }
+ Some("blocklist-remove" | "Br") => {
+ if let Some(ip) = fds.next() {
+ if ip == "all" {
+ BLOCKLIST.write().await.clear();
+ } else {
+ for ip in ip.split("|") {
+ BLOCKLIST.write().await.remove(ip);
+ }
+ }
+ }
+ }
+ Some("blocklist" | "B") => {
+ if let Some(ip) = fds.next() {
+ res = format!("{}\n", BLOCKLIST.read().await.get(ip).is_some());
+ } else {
+ for ip in BLOCKLIST.read().await.clone().into_iter() {
+ res += &format!("{}\n", ip);
+ }
+ }
+ }
+ Some("downgrade-threshold" | "dt") => {
+ if let Some(v) = fds.next() {
+ if let Ok(v) = v.parse::<f64>() {
+ if v > 0. {
+ unsafe {
+ DOWNGRADE_THRESHOLD = v;
+ }
+ }
+ }
+ } else {
+ unsafe {
+ res = format!("{}\n", DOWNGRADE_THRESHOLD);
+ }
+ }
+ }
+ Some("downgrade-start-check" | "t") => {
+ if let Some(v) = fds.next() {
+ if let Ok(v) = v.parse::<usize>() {
+ if v > 0 {
+ unsafe {
+ DOWNGRADE_START_CHECK = v * 1000;
+ }
+ }
+ }
+ } else {
+ unsafe {
+ res = format!("{}s\n", DOWNGRADE_START_CHECK / 1000);
+ }
+ }
+ }
+ Some("limit-speed" | "ls") => {
+ if let Some(v) = fds.next() {
+ if let Ok(v) = v.parse::<f64>() {
+ if v > 0. {
+ unsafe {
+ LIMIT_SPEED = (v * 1024. * 1024.) as _;
+ }
+ }
+ }
+ } else {
+ unsafe {
+ res = format!("{}Mb/s\n", LIMIT_SPEED as f64 / 1024. / 1024.);
+ }
+ }
+ }
+ Some("total-bandwidth" | "tb") => {
+ if let Some(v) = fds.next() {
+ if let Ok(v) = v.parse::<f64>() {
+ if v > 0. {
+ unsafe {
+ TOTAL_BANDWIDTH = (v * 1024. * 1024.) as _;
+ limiter.set_speed_limit(TOTAL_BANDWIDTH as _);
+ }
+ }
+ }
+ } else {
+ unsafe {
+ res = format!("{}Mb/s\n", TOTAL_BANDWIDTH as f64 / 1024. / 1024.);
+ }
+ }
+ }
+ Some("single-bandwidth" | "sb") => {
+ if let Some(v) = fds.next() {
+ if let Ok(v) = v.parse::<f64>() {
+ if v > 0. {
+ unsafe {
+ SINGLE_BANDWIDTH = (v * 1024. * 1024.) as _;
+ }
+ }
+ }
+ } else {
+ unsafe {
+ res = format!("{}Mb/s\n", SINGLE_BANDWIDTH as f64 / 1024. / 1024.);
+ }
+ }
+ }
+ Some("usage" | "u") => {
+ let mut tmp: Vec<(String, Usage)> = USAGE
+ .read()
+ .await
+ .iter()
+ .map(|x| (x.0.clone(), x.1.clone()))
+ .collect();
+ tmp.sort_by(|a, b| ((b.1).1).partial_cmp(&(a.1).1).unwrap());
+ for (ip, (elapsed, total, highest, speed)) in tmp {
+ if elapsed <= 0 {
+ continue;
+ }
+ res += &format!(
+ "{}: {}s {:.2}MB {}kb/s {}kb/s {}kb/s\n",
+ ip,
+ elapsed / 1000,
+ total as f64 / 1024. / 1024. / 8.,
+ highest,
+ total / elapsed,
+ speed
+ );
+ }
+ }
+ _ => {}
+ }
+ res
+}
+
+async fn io_loop(listener: TcpListener, listener2: TcpListener, key: &str) {
+ check_params();
+ let limiter = <Limiter>::new(unsafe { TOTAL_BANDWIDTH as _ });
loop {
tokio::select! {
- Ok((stream, addr)) = listener.accept() => {
- let key = key.to_owned();
- tokio::spawn(async move {
- make_pair(FramedStream::from(stream), addr, &key).await.ok();
- });
+ res = listener.accept() => {
+ match res {
+ Ok((stream, addr)) => {
+ stream.set_nodelay(true).ok();
+ handle_connection(stream, addr, &limiter, key, false).await;
+ }
+ Err(err) => {
+ log::error!("listener.accept failed: {}", err);
+ break;
+ }
+ }
}
- _ = timer.tick() => {
- if *stop.lock().unwrap() {
- log::info!("Stopped");
- break;
+ res = listener2.accept() => {
+ match res {
+ Ok((stream, addr)) => {
+ stream.set_nodelay(true).ok();
+ handle_connection(stream, addr, &limiter, key, true).await;
+ }
+ Err(err) => {
+ log::error!("listener2.accept failed: {}", err);
+ break;
+ }
}
}
}
}
}
-async fn make_pair(stream: FramedStream, addr: SocketAddr, key: &str) -> ResultType<()> {
+async fn handle_connection(
+ stream: TcpStream,
+ addr: SocketAddr,
+ limiter: &Limiter,
+ key: &str,
+ ws: bool,
+) {
+ let ip = addr.ip().to_string();
+ if !ws && ip == "127.0.0.1" {
+ let limiter = limiter.clone();
+ tokio::spawn(async move {
+ let mut stream = stream;
+ let mut buffer = [0; 64];
+ if let Ok(Ok(n)) = timeout(1000, stream.read(&mut buffer[..])).await {
+ if let Ok(data) = std::str::from_utf8(&buffer[..n]) {
+ let res = check_cmd(data, limiter).await;
+ stream.write(res.as_bytes()).await.ok();
+ }
+ }
+ });
+ return;
+ }
+ if BLOCKLIST.read().await.get(&ip).is_some() {
+ log::info!("{} blocked", ip);
+ return;
+ }
+ let key = key.to_owned();
+ let limiter = limiter.clone();
+ tokio::spawn(async move {
+ allow_err!(make_pair(stream, addr, &key, limiter, ws).await);
+ });
+}
+
+async fn make_pair(
+ stream: TcpStream,
+ addr: SocketAddr,
+ key: &str,
+ limiter: Limiter,
+ ws: bool,
+) -> ResultType<()> {
+ if ws {
+ make_pair_(
+ tokio_tungstenite::accept_async(stream).await?,
+ addr,
+ key,
+ limiter,
+ )
+ .await;
+ } else {
+ make_pair_(FramedStream::from(stream, addr), addr, key, limiter).await;
+ }
+ Ok(())
+}
+
+async fn make_pair_(stream: impl StreamTrait, addr: SocketAddr, key: &str, limiter: Limiter) {
let mut stream = stream;
- if let Some(Ok(bytes)) = stream.next_timeout(30_000).await {
+ if let Ok(Some(Ok(bytes))) = timeout(30_000, stream.recv()).await {
if let Ok(msg_in) = RendezvousMessage::parse_from_bytes(&bytes) {
if let Some(rendezvous_message::Union::request_relay(rf)) = msg_in.union {
if !key.is_empty() && rf.licence_key != key {
- return Ok(());
+ return;
}
if !rf.uuid.is_empty() {
- let peer = PEERS.lock().unwrap().remove(&rf.uuid);
- if let Some(peer) = peer {
- log::info!("Forward request {} from {} got paired", rf.uuid, addr);
- return relay(stream, peer).await;
+ let mut peer = PEERS.lock().await.remove(&rf.uuid);
+ if let Some(peer) = peer.as_mut() {
+ log::info!("Relayrequest {} from {} got paired", rf.uuid, addr);
+ let id = format!("{}:{}", addr.ip(), addr.port());
+ USAGE.write().await.insert(id.clone(), Default::default());
+ if !stream.is_ws() && !peer.is_ws() {
+ peer.set_raw();
+ stream.set_raw();
+ log::info!("Both are raw");
+ }
+ if let Err(err) = relay(addr, &mut stream, peer, limiter, id.clone()).await
+ {
+ log::info!("Relay of {} closed: {}", addr, err);
+ } else {
+ log::info!("Relay of {} closed", addr);
+ }
+ USAGE.write().await.remove(&id);
} else {
log::info!("New relay request {} from {}", rf.uuid, addr);
- PEERS.lock().unwrap().insert(rf.uuid.clone(), stream);
+ PEERS.lock().await.insert(rf.uuid.clone(), Box::new(stream));
sleep(30.).await;
- PEERS.lock().unwrap().remove(&rf.uuid);
+ PEERS.lock().await.remove(&rf.uuid);
}
}
}
}
}
- Ok(())
}
-async fn relay(stream: FramedStream, peer: FramedStream) -> ResultType<()> {
- let mut peer = peer;
- let mut stream = stream;
- peer.set_raw();
- stream.set_raw();
+async fn relay(
+ addr: SocketAddr,
+ stream: &mut impl StreamTrait,
+ peer: &mut Box<dyn StreamTrait>,
+ total_limiter: Limiter,
+ id: String,
+) -> ResultType<()> {
+ let ip = addr.ip().to_string();
+ let mut tm = std::time::Instant::now();
+ let mut elapsed = 0;
+ let mut total = 0;
+ let mut total_s = 0;
+ let mut highest_s = 0;
+ let mut downgrade: bool = false;
+ let mut blacked: bool = false;
+ let limiter = <Limiter>::new(unsafe { SINGLE_BANDWIDTH as _ });
+ let blacklist_limiter = <Limiter>::new(unsafe { LIMIT_SPEED as _ });
+ let downgrade_threshold =
+ (unsafe { SINGLE_BANDWIDTH as f64 * DOWNGRADE_THRESHOLD } / 1000.) as usize; // in bit/ms
+ let mut timer = interval(Duration::from_secs(3));
+ let mut last_recv_time = std::time::Instant::now();
loop {
tokio::select! {
- res = peer.next() => {
+ res = peer.recv() => {
if let Some(Ok(bytes)) = res {
- stream.send_bytes(bytes.into()).await?;
+ last_recv_time = std::time::Instant::now();
+ let nb = bytes.len() * 8;
+ if blacked || downgrade {
+ blacklist_limiter.consume(nb).await;
+ } else {
+ limiter.consume(nb).await;
+ }
+ total_limiter.consume(nb).await;
+ total += nb;
+ total_s += nb;
+ if bytes.len() > 0 {
+ stream.send_raw(bytes.into()).await?;
+ }
} else {
break;
}
},
- res = stream.next() => {
+ res = stream.recv() => {
if let Some(Ok(bytes)) = res {
- peer.send_bytes(bytes.into()).await?;
+ last_recv_time = std::time::Instant::now();
+ let nb = bytes.len() * 8;
+ if blacked || downgrade {
+ blacklist_limiter.consume(nb).await;
+ } else {
+ limiter.consume(nb).await;
+ }
+ total_limiter.consume(nb).await;
+ total += nb;
+ total_s += nb;
+ if bytes.len() > 0 {
+ peer.send_raw(bytes.into()).await?;
+ }
} else {
break;
}
},
+ _ = timer.tick() => {
+ if last_recv_time.elapsed().as_secs() > 30 {
+ bail!("Timeout");
+ }
+ }
+ }
+
+ let n = tm.elapsed().as_millis() as usize;
+ if n >= 1_000 {
+ if BLOCKLIST.read().await.get(&ip).is_some() {
+ log::info!("{} blocked", ip);
+ break;
+ }
+ blacked = BLACKLIST.read().await.get(&ip).is_some();
+ tm = std::time::Instant::now();
+ let speed = total_s / (n as usize);
+ if speed > highest_s {
+ highest_s = speed;
+ }
+ elapsed += n;
+ USAGE.write().await.insert(
+ id.clone(),
+ (elapsed as _, total as _, highest_s as _, speed as _),
+ );
+ total_s = 0;
+ if elapsed > unsafe { DOWNGRADE_START_CHECK } && !downgrade {
+ if total > elapsed * downgrade_threshold {
+ downgrade = true;
+ log::info!(
+ "Downgrade {}, exceed downgrade threshold {}bit/ms in {}ms",
+ id,
+ downgrade_threshold,
+ elapsed
+ );
+ }
+ }
}
}
Ok(())
}
+
+fn get_server_sk(key: &str) -> String {
+ let mut key = key.to_owned();
+ if let Ok(sk) = base64::decode(&key) {
+ if sk.len() == sign::SECRETKEYBYTES {
+ log::info!("The key is a crypto private key");
+ key = base64::encode(&sk[(sign::SECRETKEYBYTES / 2)..]);
+ }
+ }
+
+ if key == "-" || key == "_" {
+ let (pk, _) = crate::common::gen_sk();
+ key = pk;
+ }
+
+ if !key.is_empty() {
+ log::info!("Key: {}", key);
+ }
+
+ key
+}
+
+#[async_trait]
+trait StreamTrait: Send + Sync + 'static {
+ async fn recv(&mut self) -> Option<Result<BytesMut, Error>>;
+ async fn send_raw(&mut self, bytes: Bytes) -> ResultType<()>;
+ fn is_ws(&self) -> bool;
+ fn set_raw(&mut self);
+}
+
+#[async_trait]
+impl StreamTrait for FramedStream {
+ async fn recv(&mut self) -> Option<Result<BytesMut, Error>> {
+ self.next().await
+ }
+
+ async fn send_raw(&mut self, bytes: Bytes) -> ResultType<()> {
+ self.send_bytes(bytes).await
+ }
+
+ fn is_ws(&self) -> bool {
+ false
+ }
+
+ fn set_raw(&mut self) {
+ self.set_raw();
+ }
+}
+
+#[async_trait]
+impl StreamTrait for tokio_tungstenite::WebSocketStream<TcpStream> {
+ async fn recv(&mut self) -> Option<Result<BytesMut, Error>> {
+ if let Some(msg) = self.next().await {
+ match msg {
+ Ok(msg) => {
+ match msg {
+ tungstenite::Message::Binary(bytes) => {
+ Some(Ok(bytes[..].into())) // to-do: poor performance
+ }
+ _ => Some(Ok(BytesMut::new())),
+ }
+ }
+ Err(err) => Some(Err(Error::new(std::io::ErrorKind::Other, err.to_string()))),
+ }
+ } else {
+ None
+ }
+ }
+
+ async fn send_raw(&mut self, bytes: Bytes) -> ResultType<()> {
+ Ok(self
+ .send(tungstenite::Message::Binary(bytes.to_vec()))
+ .await?) // to-do: poor performance
+ }
+
+ fn is_ws(&self) -> bool {
+ true
+ }
+
+ fn set_raw(&mut self) {}
+}
diff --git a/src/rendezvous_server.rs b/src/rendezvous_server.rs
index 8f9e5f1..abe319d 100644
--- a/src/rendezvous_server.rs
+++ b/src/rendezvous_server.rs
@@ -1,212 +1,193 @@
+use crate::common::*;
+use crate::peer::*;
use hbb_common::{
allow_err,
bytes::{Bytes, BytesMut},
bytes_codec::BytesCodec,
+ futures::future::join_all,
futures_util::{
sink::SinkExt,
stream::{SplitSink, StreamExt},
},
log,
protobuf::{Message as _, MessageField},
- rendezvous_proto::*,
- sleep,
+ rendezvous_proto::{
+ register_pk_response::Result::{TOO_FREQUENT, UUID_MISMATCH},
+ *,
+ },
tcp::{new_listener, FramedStream},
timeout,
tokio::{
self,
+ io::{AsyncReadExt, AsyncWriteExt},
net::{TcpListener, TcpStream},
- sync::mpsc,
+ sync::{mpsc, Mutex},
time::{interval, Duration},
},
tokio_util::codec::Framed,
udp::FramedSocket,
AddrMangle, ResultType,
};
-use serde_derive::{Deserialize, Serialize};
+use sodiumoxide::crypto::sign;
use std::{
collections::HashMap,
- net::SocketAddr,
- sync::{Arc, Mutex, RwLock},
+ net::{IpAddr, Ipv4Addr, SocketAddr},
+ sync::Arc,
time::Instant,
};
+const ADDR_127: IpAddr = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1));
#[derive(Clone, Debug)]
-struct Peer {
- socket_addr: SocketAddr,
- last_reg_time: Instant,
- uuid: Vec<u8>,
- pk: Vec<u8>,
-}
-
-impl Default for Peer {
- fn default() -> Self {
- Self {
- socket_addr: "0.0.0.0:0".parse().unwrap(),
- last_reg_time: Instant::now()
- .checked_sub(std::time::Duration::from_secs(3600))
- .unwrap(),
- uuid: Vec::new(),
- pk: Vec::new(),
- }
- }
-}
-
-#[derive(Debug, Serialize, Deserialize, Default)]
-struct PeerSerde {
- #[serde(default)]
- ip: String,
- #[serde(default)]
- uuid: Vec<u8>,
- #[serde(default)]
- pk: Vec<u8>,
-}
-
-#[derive(Clone)]
-struct PeerMap {
- map: Arc<RwLock<HashMap<String, Peer>>>,
- db: super::SledAsync,
-}
-
-pub const DEFAULT_PORT: &'static str = "21116";
-
-impl PeerMap {
- fn new() -> ResultType<Self> {
- let mut db: String = "hbbs.db".to_owned();
- #[cfg(windows)]
- {
- if let Some(path) = hbb_common::config::Config::icon_path().parent() {
- db = format!("{}\\{}", path.to_str().unwrap_or("."), db);
- }
- }
- #[cfg(not(windows))]
- {
- db = format!("./{}", db);
- }
- Ok(Self {
- map: Default::default(),
- db: super::SledAsync::new(&db, true)?,
- })
- }
-
- #[inline]
- fn update_pk(&mut self, id: String, socket_addr: SocketAddr, uuid: Vec<u8>, pk: Vec<u8>) {
- log::info!("update_pk {} {:?} {:?} {:?}", id, socket_addr, uuid, pk);
- let mut lock = self.map.write().unwrap();
- lock.insert(
- id.clone(),
- Peer {
- socket_addr,
- last_reg_time: Instant::now(),
- uuid: uuid.clone(),
- pk: pk.clone(),
- },
- );
- drop(lock);
- let ip = socket_addr.ip().to_string();
- self.db.insert(id, PeerSerde { ip, uuid, pk });
- }
-
- #[inline]
- async fn get(&mut self, id: &str) -> Option<Peer> {
- let p = self.map.read().unwrap().get(id).map(|x| x.clone());
- if p.is_some() {
- return p;
- } else {
- let id = id.to_owned();
- let v = self.db.get(id.clone()).await;
- if let Some(v) = super::SledAsync::deserialize::<PeerSerde>(&v) {
- self.map.write().unwrap().insert(
- id,
- Peer {
- uuid: v.uuid,
- pk: v.pk,
- ..Default::default()
- },
- );
- return Some(Peer::default());
- }
- }
- None
- }
-
- #[inline]
- fn is_in_memory(&self, id: &str) -> bool {
- self.map.read().unwrap().contains_key(id)
- }
+enum Data {
+ Msg(RendezvousMessage, SocketAddr),
+ RelayServers0(String),
+ RelayServers(RelayServers),
}
const REG_TIMEOUT: i32 = 30_000;
-type Sink = SplitSink<Framed<TcpStream, BytesCodec>, Bytes>;
-type Sender = mpsc::UnboundedSender<(RendezvousMessage, SocketAddr)>;
-type Receiver = mpsc::UnboundedReceiver<(RendezvousMessage, SocketAddr)>;
+type TcpStreamSink = SplitSink<Framed<TcpStream, BytesCodec>, Bytes>;
+type WsSink = SplitSink<tokio_tungstenite::WebSocketStream<TcpStream>, tungstenite::Message>;
+enum Sink {
+ TcpStream(TcpStreamSink),
+ Ws(WsSink),
+}
+type Sender = mpsc::UnboundedSender<Data>;
+type Receiver = mpsc::UnboundedReceiver<Data>;
static mut ROTATION_RELAY_SERVER: usize = 0;
+type RelayServers = Vec<String>;
+static CHECK_RELAY_TIMEOUT: u64 = 3_000;
+static mut ALWAYS_USE_RELAY: bool = false;
#[derive(Clone)]
pub struct RendezvousServer {
tcp_punch: Arc<Mutex<HashMap<SocketAddr, Sink>>>,
pm: PeerMap,
tx: Sender,
- relay_servers: Vec<String>,
+ relay_servers: Arc<RelayServers>,
+ relay_servers0: Arc<RelayServers>,
serial: i32,
- rendezvous_servers: Vec<String>,
+ rendezvous_servers: Arc<Vec<String>>,
version: String,
software_url: String,
+ sk: Option<sign::SecretKey>,
+}
+
+enum LoopFailure {
+ UdpSocket,
+ Listener3,
+ Listener2,
+ Listener,
}
impl RendezvousServer {
- #[tokio::main(basic_scheduler)]
+ #[tokio::main(flavor = "multi_thread")]
pub async fn start(
- addr: &str,
- addr2: &str,
- relay_servers: Vec<String>,
+ port: i32,
serial: i32,
- rendezvous_servers: Vec<String>,
- software_url: String,
key: &str,
- stop: Arc<Mutex<bool>>,
id_change_support: bool,
+ rmem: usize,
) -> ResultType<()> {
- if !key.is_empty() {
- log::info!("Key: {}", key);
+ let addr = format!("0.0.0.0:{}", port);
+ let addr2 = format!("0.0.0.0:{}", port - 1);
+ let addr3 = format!("0.0.0.0:{}", port + 2);
+ let pm = PeerMap::new().await?;
+ #[cfg(not(debug_assertions))]
+ if !crate::lic::check_lic(&get_arg("email"), crate::version::VERSION) {
+ return Ok(());
}
+ log::info!("serial={}", serial);
+ let rendezvous_servers = get_servers(&get_arg("rendezvous-servers"), "rendezvous-servers");
log::info!("Listening on tcp/udp {}", addr);
log::info!("Listening on tcp {}, extra port for NAT test", addr2);
- log::info!("relay-servers={:?}", relay_servers);
+ log::info!("Listening on websocket {}", addr3);
log::info!("change-id={:?}", id_change_support);
- let mut socket = FramedSocket::new(addr).await?;
- let (tx, mut rx) = mpsc::unbounded_channel::<(RendezvousMessage, SocketAddr)>();
+ let mut socket = FramedSocket::new_with_buf_size(&addr, rmem).await?;
+ let (tx, mut rx) = mpsc::unbounded_channel::<Data>();
+ let software_url = get_arg("software-url");
let version = hbb_common::get_version_from_url(&software_url);
if !version.is_empty() {
log::info!("software_url: {}, version: {}", software_url, version);
}
let mut rs = Self {
tcp_punch: Arc::new(Mutex::new(HashMap::new())),
- pm: PeerMap::new()?,
+ pm,
tx: tx.clone(),
- relay_servers,
+ relay_servers: Default::default(),
+ relay_servers0: Default::default(),
serial,
- rendezvous_servers,
+ rendezvous_servers: Arc::new(rendezvous_servers),
version,
software_url,
+ sk: None,
};
- let mut listener = new_listener(addr, false).await?;
- let mut listener2 = new_listener(addr2, false).await?;
- loop {
- if *stop.lock().unwrap() {
- sleep(0.1).await;
- continue;
+ let key = rs.get_server_sk(key);
+ std::env::set_var("PORT_FOR_API", port.to_string());
+ rs.parse_relay_servers(&get_arg("relay-servers"));
+ let pm = rs.pm.clone();
+ let mut listener = new_listener(&addr, false).await?;
+ let mut listener2 = new_listener(&addr2, false).await?;
+ let mut listener3 = new_listener(&addr3, false).await?;
+ let test_addr = std::env::var("TEST_HBBS").unwrap_or_default();
+ if std::env::var("ALWAYS_USE_RELAY")
+ .unwrap_or_default()
+ .to_uppercase()
+ == "Y"
+ {
+ unsafe {
+ ALWAYS_USE_RELAY = true;
+ }
+ }
+ log::info!(
+ "ALWAYS_USE_RELAY={}",
+ if unsafe { ALWAYS_USE_RELAY } {
+ "Y"
+ } else {
+ "N"
}
+ );
+ if test_addr.to_lowercase() != "no" {
+ let test_addr = (if test_addr.is_empty() {
+ addr.replace("0.0.0.0", "127.0.0.1")
+ } else {
+ test_addr
+ })
+ .parse::<SocketAddr>()?;
+ tokio::spawn(async move {
+ allow_err!(test_hbbs(test_addr).await);
+ });
+ };
+ loop {
log::info!("Start");
- rs.io_loop(
- &mut rx,
- &mut listener,
- &mut listener2,
- &mut socket,
- key,
- stop.clone(),
- id_change_support,
- )
- .await;
+ match rs
+ .io_loop(
+ &mut rx,
+ &mut listener,
+ &mut listener2,
+ &mut listener3,
+ &mut socket,
+ &key,
+ id_change_support,
+ )
+ .await
+ {
+ LoopFailure::UdpSocket => {
+ drop(socket);
+ socket = FramedSocket::new_with_buf_size(&addr, rmem).await?;
+ }
+ LoopFailure::Listener => {
+ drop(listener);
+ listener = new_listener(&addr, false).await?;
+ }
+ LoopFailure::Listener2 => {
+ drop(listener2);
+ listener2 = new_listener(&addr2, false).await?;
+ }
+ LoopFailure::Listener3 => {
+ drop(listener3);
+ listener3 = new_listener(&addr3, false).await?;
+ }
+ }
}
}
@@ -215,161 +196,89 @@ impl RendezvousServer {
rx: &mut Receiver,
listener: &mut TcpListener,
listener2: &mut TcpListener,
+ listener3: &mut TcpListener,
socket: &mut FramedSocket,
key: &str,
- stop: Arc<Mutex<bool>>,
id_change_support: bool,
- ) {
- let mut timer = interval(Duration::from_millis(100));
+ ) -> LoopFailure {
+ let mut timer_check_relay = interval(Duration::from_millis(CHECK_RELAY_TIMEOUT));
loop {
tokio::select! {
- _ = timer.tick() => {
- if *stop.lock().unwrap() {
- log::info!("Stopped");
- break;
- }
- }
- Some((msg, addr)) = rx.recv() => {
- allow_err!(socket.send(&msg, addr).await);
- }
- Some(Ok((bytes, addr))) = socket.next() => {
- allow_err!(self.handle_msg(&bytes, addr, socket, key).await);
- }
- Ok((stream, addr)) = listener2.accept() => {
- let stream = FramedStream::from(stream);
- tokio::spawn(async move {
- let mut stream = stream;
- if let Some(Ok(bytes)) = stream.next_timeout(30_000).await {
- if let Ok(msg_in) = RendezvousMessage::parse_from_bytes(&bytes) {
- if let Some(rendezvous_message::Union::test_nat_request(_)) = msg_in.union {
- let mut msg_out = RendezvousMessage::new();
- msg_out.set_test_nat_response(TestNatResponse {
- port: addr.port() as _,
- ..Default::default()
- });
- stream.send(&msg_out).await.ok();
- }
+ _ = timer_check_relay.tick() => {
+ if self.relay_servers0.len() > 1 {
+ let rs = self.relay_servers0.clone();
+ let tx = self.tx.clone();
+ tokio::spawn(async move {
+ check_relay_servers(rs, tx).await;
+ });
+ }
+ }
+ Some(data) = rx.recv() => {
+ match data {
+ Data::Msg(msg, addr) => { allow_err!(socket.send(&msg, addr).await); }
+ Data::RelayServers0(rs) => { self.parse_relay_servers(&rs); }
+ Data::RelayServers(rs) => { self.relay_servers = Arc::new(rs); }
+ }
+ }
+ res = socket.next() => {
+ match res {
+ Some(Ok((bytes, addr))) => {
+ if let Err(err) = self.handle_udp(&bytes, addr.into(), socket, key).await {
+ log::error!("udp failure: {}", err);
+ return LoopFailure::UdpSocket;
}
}
- });
+ Some(Err(err)) => {
+ log::error!("udp failure: {}", err);
+ return LoopFailure::UdpSocket;
+ }
+ None => {
+ // unreachable!() ?
+ }
+ }
}
- Ok((stream, addr)) = listener.accept() => {
- log::debug!("Tcp connection from {:?}", addr);
- let (a, mut b) = Framed::new(stream, BytesCodec::new()).split();
- let tcp_punch = self.tcp_punch.clone();
- let mut rs = self.clone();
- let key = key.to_owned();
- tokio::spawn(async move {
- let mut sender = Some(a);
- while let Ok(Some(Ok(bytes))) = timeout(30_000, b.next()).await {
- if let Ok(msg_in) = RendezvousMessage::parse_from_bytes(&bytes) {
- match msg_in.union {
- Some(rendezvous_message::Union::punch_hole_request(ph)) => {
- // there maybe several attempt, so sender can be none
- if let Some(sender) = sender.take() {
- tcp_punch.lock().unwrap().insert(addr, sender);
- }
- allow_err!(rs.handle_tcp_punch_hole_request(addr, ph, &key).await);
- }
- Some(rendezvous_message::Union::request_relay(mut rf)) => {
- // there maybe several attempt, so sender can be none
- if let Some(sender) = sender.take() {
- tcp_punch.lock().unwrap().insert(addr, sender);
- }
- if let Some(peer) = rs.pm.map.read().unwrap().get(&rf.id).map(|x| x.clone()) {
- let mut msg_out = RendezvousMessage::new();
- rf.socket_addr = AddrMangle::encode(addr);
- msg_out.set_request_relay(rf);
- rs.tx.send((msg_out, peer.socket_addr)).ok();
- }
- }
- Some(rendezvous_message::Union::relay_response(mut rr)) => {
- let addr_b = AddrMangle::decode(&rr.socket_addr);
- rr.socket_addr = Default::default();
- let id = rr.get_id();
- if !id.is_empty() {
- if let Some(peer) = rs.pm.get(&id).await {
- rr.set_pk(peer.pk.clone());
- }
- }
- let mut msg_out = RendezvousMessage::new();
- msg_out.set_relay_response(rr);
- allow_err!(rs.send_to_tcp_sync(&msg_out, addr_b).await);
- break;
- }
- Some(rendezvous_message::Union::punch_hole_sent(phs)) => {
- allow_err!(rs.handle_hole_sent(phs, addr, None).await);
- break;
- }
- Some(rendezvous_message::Union::local_addr(la)) => {
- allow_err!(rs.handle_local_addr(la, addr, None).await);
- break;
- }
- Some(rendezvous_message::Union::test_nat_request(tar)) => {
- let mut msg_out = RendezvousMessage::new();
- let mut res = TestNatResponse {
- port: addr.port() as _,
- ..Default::default()
- };
- if rs.serial > tar.serial {
- let mut cu = ConfigUpdate::new();
- cu.serial = rs.serial;
- cu.rendezvous_servers = rs.rendezvous_servers.clone();
- res.cu = MessageField::from_option(Some(cu));
- }
- msg_out.set_test_nat_response(res);
- if let Some(tcp) = sender.as_mut() {
- if let Ok(bytes) = msg_out.write_to_bytes() {
- allow_err!(tcp.send(Bytes::from(bytes)).await);
- }
- }
- break;
- }
- Some(rendezvous_message::Union::register_pk(rk)) => {
- if rk.uuid.is_empty() {
- break;
- }
- let mut res = register_pk_response::Result::OK;
- if !id_change_support {
- res = register_pk_response::Result::NOT_SUPPORT;
- } else if !hbb_common::is_valid_custom_id(&rk.id) {
- res = register_pk_response::Result::INVALID_ID_FORMAT;
- } else if let Some(peer) = rs.pm.get(&rk.id).await {
- if peer.uuid != rk.uuid {
- res = register_pk_response::Result::ID_EXISTS;
- }
- }
- let mut msg_out = RendezvousMessage::new();
- msg_out.set_register_pk_response(RegisterPkResponse {
- result: res.into(),
- ..Default::default()
- });
- if let Some(tcp) = sender.as_mut() {
- if let Ok(bytes) = msg_out.write_to_bytes() {
- allow_err!(tcp.send(Bytes::from(bytes)).await);
- }
- }
- }
- _ => {
- break;
- }
- }
- } else {
- break;
- }
+ res = listener2.accept() => {
+ match res {
+ Ok((stream, addr)) => {
+ stream.set_nodelay(true).ok();
+ self.handle_listener2(stream, addr).await;
}
- if sender.is_none() {
- rs.tcp_punch.lock().unwrap().remove(&addr);
+ Err(err) => {
+ log::error!("listener2.accept failed: {}", err);
+ return LoopFailure::Listener2;
}
- log::debug!("Tcp connection from {:?} closed", addr);
- });
+ }
+ }
+ res = listener3.accept() => {
+ match res {
+ Ok((stream, addr)) => {
+ stream.set_nodelay(true).ok();
+ self.handle_listener(stream, addr, key, id_change_support, true).await;
+ }
+ Err(err) => {
+ log::error!("listener3.accept failed: {}", err);
+ return LoopFailure::Listener3;
+ }
+ }
+ }
+ res = listener.accept() => {
+ match res {
+ Ok((stream, addr)) => {
+ stream.set_nodelay(true).ok();
+ self.handle_listener(stream, addr, key, id_change_support, false).await;
+ }
+ Err(err) => {
+ log::error!("listener.accept failed: {}", err);
+ return LoopFailure::Listener;
+ }
+ }
}
}
}
}
#[inline]
- async fn handle_msg(
+ async fn handle_udp(
&mut self,
bytes: &BytesMut,
addr: SocketAddr,
@@ -387,7 +296,7 @@ impl RendezvousServer {
let mut msg_out = RendezvousMessage::new();
msg_out.set_configure_update(ConfigUpdate {
serial: self.serial,
- rendezvous_servers: self.rendezvous_servers.clone(),
+ rendezvous_servers: (*self.rendezvous_servers).clone(),
..Default::default()
});
socket.send(&msg_out, addr).await?;
@@ -395,39 +304,94 @@ impl RendezvousServer {
}
}
Some(rendezvous_message::Union::register_pk(rk)) => {
- if rk.uuid.is_empty() {
+ if rk.uuid.is_empty() || rk.pk.is_empty() {
return Ok(());
}
let id = rk.id;
- let mut res = register_pk_response::Result::OK;
+ let ip = addr.ip().to_string();
if id.len() < 6 {
- res = register_pk_response::Result::UUID_MISMATCH;
- } else if let Some(peer) = self.pm.get(&id).await {
+ return send_rk_res(socket, addr, UUID_MISMATCH).await;
+ } else if !self.check_ip_blocker(&ip, &id).await {
+ return send_rk_res(socket, addr, TOO_FREQUENT).await;
+ }
+ let peer = self.pm.get_or(&id).await;
+ let (changed, ip_changed) = {
+ let peer = peer.read().await;
if peer.uuid.is_empty() {
- self.pm.update_pk(id, addr, rk.uuid, rk.pk);
- } else if peer.uuid != rk.uuid {
- log::warn!(
- "Peer {} uuid mismatch: {:?} vs {:?}",
- id,
- rk.uuid,
- peer.uuid
+ (true, false)
+ } else {
+ if peer.uuid == rk.uuid {
+ if peer.info.ip != ip && peer.pk != rk.pk {
+ log::warn!(
+ "Peer {} ip/pk mismatch: {}/{:?} vs {}/{:?}",
+ id,
+ ip,
+ rk.pk,
+ peer.info.ip,
+ peer.pk,
+ );
+ drop(peer);
+ return send_rk_res(socket, addr, UUID_MISMATCH).await;
+ }
+ } else {
+ log::warn!(
+ "Peer {} uuid mismatch: {:?} vs {:?}",
+ id,
+ rk.uuid,
+ peer.uuid
+ );
+ drop(peer);
+ return send_rk_res(socket, addr, UUID_MISMATCH).await;
+ }
+ let ip_changed = peer.info.ip != ip;
+ (
+ peer.uuid != rk.uuid || peer.pk != rk.pk || ip_changed,
+ ip_changed,
+ )
+ }
+ };
+ let mut req_pk = peer.read().await.reg_pk;
+ if req_pk.1.elapsed().as_secs() > 6 {
+ req_pk.0 = 0;
+ } else if req_pk.0 > 2 {
+ return send_rk_res(socket, addr, TOO_FREQUENT).await;
+ }
+ req_pk.0 += 1;
+ req_pk.1 = Instant::now();
+ peer.write().await.reg_pk = req_pk;
+ if ip_changed {
+ let mut lock = IP_CHANGES.lock().await;
+ if let Some((tm, ips)) = lock.get_mut(&id) {
+ if tm.elapsed().as_secs() > IP_CHANGE_DUR {
+ *tm = Instant::now();
+ ips.clear();
+ ips.insert(ip.clone(), 1);
+ } else {
+ if let Some(v) = ips.get_mut(&ip) {
+ *v += 1;
+ } else {
+ ips.insert(ip.clone(), 1);
+ }
+ }
+ } else {
+ lock.insert(
+ id.clone(),
+ (Instant::now(), HashMap::from([(ip.clone(), 1)])),
);
- res = register_pk_response::Result::UUID_MISMATCH;
- } else if peer.pk != rk.pk {
- self.pm.update_pk(id, addr, rk.uuid, rk.pk);
}
- } else {
- self.pm.update_pk(id, addr, rk.uuid, rk.pk);
+ }
+ if changed {
+ self.pm.update_pk(id, peer, addr, rk.uuid, rk.pk, ip).await;
}
let mut msg_out = RendezvousMessage::new();
msg_out.set_register_pk_response(RegisterPkResponse {
- result: res.into(),
+ result: register_pk_response::Result::OK.into(),
..Default::default()
});
socket.send(&msg_out, addr).await?
}
Some(rendezvous_message::Union::punch_hole_request(ph)) => {
- if self.pm.is_in_memory(&ph.id) {
+ if self.pm.is_in_memory(&ph.id).await {
self.handle_udp_punch_hole_request(addr, ph, key).await?;
} else {
// not in memory, fetch from db with spawn in case blocking me
@@ -445,18 +409,17 @@ impl RendezvousServer {
self.handle_local_addr(la, addr, Some(socket)).await?;
}
Some(rendezvous_message::Union::configure_update(mut cu)) => {
- if addr.ip() == std::net::IpAddr::V4(std::net::Ipv4Addr::new(127, 0, 0, 1))
- && cu.serial > self.serial
- {
+ if addr.ip() == ADDR_127 && cu.serial > self.serial {
self.serial = cu.serial;
- self.rendezvous_servers = cu
- .rendezvous_servers
- .drain(..)
- .filter(|x| {
- !x.is_empty()
- && test_if_valid_server(x, "rendezvous-server").is_ok()
- })
- .collect();
+ self.rendezvous_servers = Arc::new(
+ cu.rendezvous_servers
+ .drain(..)
+ .filter(|x| {
+ !x.is_empty()
+ && test_if_valid_server(x, "rendezvous-server").is_ok()
+ })
+ .collect(),
+ );
log::info!(
"configure updated: serial={} rendezvous-servers={:?}",
self.serial,
@@ -481,56 +444,129 @@ impl RendezvousServer {
}
#[inline]
+ async fn handle_tcp(
+ &mut self,
+ bytes: &[u8],
+ sink: &mut Option<Sink>,
+ addr: SocketAddr,
+ key: &str,
+ id_change_support: bool,
+ ws: bool,
+ ) -> bool {
+ if let Ok(msg_in) = RendezvousMessage::parse_from_bytes(&bytes) {
+ match msg_in.union {
+ Some(rendezvous_message::Union::punch_hole_request(ph)) => {
+ // there maybe several attempt, so sink can be none
+ if let Some(sink) = sink.take() {
+ self.tcp_punch.lock().await.insert(addr, sink);
+ }
+ allow_err!(self.handle_tcp_punch_hole_request(addr, ph, &key, ws).await);
+ return true;
+ }
+ Some(rendezvous_message::Union::request_relay(mut rf)) => {
+ // there maybe several attempt, so sink can be none
+ if let Some(sink) = sink.take() {
+ self.tcp_punch.lock().await.insert(addr, sink);
+ }
+ if let Some(peer) = self.pm.get_in_memory(&rf.id).await {
+ let mut msg_out = RendezvousMessage::new();
+ rf.socket_addr = AddrMangle::encode(addr);
+ msg_out.set_request_relay(rf);
+ let peer_addr = peer.read().await.socket_addr;
+ self.tx.send(Data::Msg(msg_out, peer_addr)).ok();
+ }
+ return true;
+ }
+ Some(rendezvous_message::Union::relay_response(mut rr)) => {
+ let addr_b = AddrMangle::decode(&rr.socket_addr);
+ rr.socket_addr = Default::default();
+ let id = rr.get_id();
+ if !id.is_empty() {
+ let pk = self.get_pk(&rr.version, id.to_owned()).await;
+ rr.set_pk(pk);
+ }
+ let mut msg_out = RendezvousMessage::new();
+ msg_out.set_relay_response(rr);
+ allow_err!(self.send_to_tcp_sync(msg_out, addr_b).await);
+ }
+ Some(rendezvous_message::Union::punch_hole_sent(phs)) => {
+ allow_err!(self.handle_hole_sent(phs, addr, None).await);
+ }
+ Some(rendezvous_message::Union::local_addr(la)) => {
+ allow_err!(self.handle_local_addr(la, addr, None).await);
+ }
+ Some(rendezvous_message::Union::test_nat_request(tar)) => {
+ let mut msg_out = RendezvousMessage::new();
+ let mut res = TestNatResponse {
+ port: addr.port() as _,
+ ..Default::default()
+ };
+ if self.serial > tar.serial {
+ let mut cu = ConfigUpdate::new();
+ cu.serial = self.serial;
+ cu.rendezvous_servers = (*self.rendezvous_servers).clone();
+ res.cu = MessageField::from_option(Some(cu));
+ }
+ msg_out.set_test_nat_response(res);
+ Self::send_to_sink(sink, msg_out).await;
+ }
+ Some(rendezvous_message::Union::register_pk(_rk)) => {
+ let res = register_pk_response::Result::NOT_SUPPORT;
+ let mut msg_out = RendezvousMessage::new();
+ msg_out.set_register_pk_response(RegisterPkResponse {
+ result: res.into(),
+ ..Default::default()
+ });
+ Self::send_to_sink(sink, msg_out).await;
+ }
+ _ => {}
+ }
+ }
+ false
+ }
+
+ #[inline]
async fn update_addr(
&mut self,
id: String,
socket_addr: SocketAddr,
socket: &mut FramedSocket,
) -> ResultType<()> {
- let mut lock = self.pm.map.write().unwrap();
- let last_reg_time = Instant::now();
- if let Some(old) = lock.get_mut(&id) {
- old.socket_addr = socket_addr;
- old.last_reg_time = last_reg_time;
- let request_pk = old.pk.is_empty();
- drop(lock);
- let mut msg_out = RendezvousMessage::new();
- msg_out.set_register_peer_response(RegisterPeerResponse {
- request_pk,
- ..Default::default()
- });
- socket.send(&msg_out, socket_addr).await?;
+ let (request_pk, ip_change) = if let Some(old) = self.pm.get_in_memory(&id).await {
+ let mut old = old.write().await;
+ let ip = socket_addr.ip();
+ let ip_change = if old.socket_addr.port() != 0 {
+ ip != old.socket_addr.ip()
+ } else {
+ ip.to_string() != old.info.ip
+ } && ip != ADDR_127;
+ let request_pk = old.pk.is_empty() || ip_change;
+ if !request_pk {
+ old.socket_addr = socket_addr;
+ old.last_reg_time = Instant::now();
+ }
+ let ip_change = if ip_change && old.reg_pk.0 <= 2 {
+ Some(if old.socket_addr.port() == 0 {
+ old.info.ip.clone()
+ } else {
+ old.socket_addr.to_string()
+ })
+ } else {
+ None
+ };
+ (request_pk, ip_change)
} else {
- drop(lock);
- let mut pm = self.pm.clone();
- let tx = self.tx.clone();
- tokio::spawn(async move {
- let v = pm.db.get(id.clone()).await;
- let (uuid, pk) = {
- if let Some(v) = super::SledAsync::deserialize::<PeerSerde>(&v) {
- (v.uuid, v.pk)
- } else {
- (Vec::new(), Vec::new())
- }
- };
- let mut msg_out = RendezvousMessage::new();
- msg_out.set_register_peer_response(RegisterPeerResponse {
- request_pk: pk.is_empty(),
- ..Default::default()
- });
- tx.send((msg_out, socket_addr)).ok();
- pm.map.write().unwrap().insert(
- id,
- Peer {
- socket_addr,
- last_reg_time,
- uuid,
- pk,
- },
- );
- });
+ (true, None)
+ };
+ if let Some(old) = ip_change {
+ log::info!("IP change of {} from {} to {}", id, old, socket_addr);
}
- Ok(())
+ let mut msg_out = RendezvousMessage::new();
+ msg_out.set_register_peer_response(RegisterPeerResponse {
+ request_pk,
+ ..Default::default()
+ });
+ socket.send(&msg_out, socket_addr).await
}
#[inline]
@@ -549,13 +585,9 @@ impl RendezvousServer {
&addr
);
let mut msg_out = RendezvousMessage::new();
- let pk = match self.pm.get(&phs.id).await {
- Some(peer) => peer.pk,
- _ => Vec::new(),
- };
let mut p = PunchHoleResponse {
socket_addr: AddrMangle::encode(addr),
- pk,
+ pk: self.get_pk(&phs.version, phs.id).await,
relay_server: phs.relay_server.clone(),
..Default::default()
};
@@ -566,7 +598,7 @@ impl RendezvousServer {
if let Some(socket) = socket {
socket.send(&msg_out, addr_a).await?;
} else {
- self.send_to_tcp(&msg_out, addr_a).await;
+ self.send_to_tcp(msg_out, addr_a).await;
}
Ok(())
}
@@ -587,17 +619,9 @@ impl RendezvousServer {
&addr
);
let mut msg_out = RendezvousMessage::new();
- let pk = if la.id.is_empty() {
- Vec::new()
- } else {
- match self.pm.get(&la.id).await {
- Some(peer) => peer.pk,
- _ => Vec::new(),
- }
- };
let mut p = PunchHoleResponse {
socket_addr: la.local_addr.clone(),
- pk,
+ pk: self.get_pk(&la.version, la.id).await,
relay_server: la.relay_server,
..Default::default()
};
@@ -606,7 +630,7 @@ impl RendezvousServer {
if let Some(socket) = socket {
socket.send(&msg_out, addr_a).await?;
} else {
- self.send_to_tcp(&msg_out, addr_a).await;
+ self.send_to_tcp(msg_out, addr_a).await;
}
Ok(())
}
@@ -617,11 +641,12 @@ impl RendezvousServer {
addr: SocketAddr,
ph: PunchHoleRequest,
key: &str,
+ ws: bool,
) -> ResultType<(RendezvousMessage, Option<SocketAddr>)> {
if !key.is_empty() && ph.licence_key != key {
let mut msg_out = RendezvousMessage::new();
msg_out.set_punch_hole_response(PunchHoleResponse {
- failure: punch_hole_response::Failure::LICENCE_MISMATCH.into(),
+ failure: punch_hole_response::Failure::LICENSE_MISMATCH.into(),
..Default::default()
});
return Ok((msg_out, None));
@@ -633,7 +658,11 @@ impl RendezvousServer {
// because punch hole won't work if in the same intranet,
// all routers will drop such self-connections.
if let Some(peer) = self.pm.get(&id).await {
- if peer.last_reg_time.elapsed().as_millis() as i32 >= REG_TIMEOUT {
+ let (elapsed, peer_addr) = {
+ let r = peer.read().await;
+ (r.last_reg_time.elapsed().as_millis() as i32, r.socket_addr)
+ };
+ if elapsed >= REG_TIMEOUT {
let mut msg_out = RendezvousMessage::new();
msg_out.set_punch_hole_response(PunchHoleResponse {
failure: punch_hole_response::Failure::OFFLINE.into(),
@@ -642,34 +671,35 @@ impl RendezvousServer {
return Ok((msg_out, None));
}
let mut msg_out = RendezvousMessage::new();
- let same_intranet = match peer.socket_addr {
- SocketAddr::V4(a) => match addr {
- SocketAddr::V4(b) => a.ip() == b.ip(),
- _ => false,
- },
- SocketAddr::V6(a) => match addr {
- SocketAddr::V6(b) => a.ip() == b.ip(),
- _ => false,
- },
- };
- let socket_addr = AddrMangle::encode(addr);
- let relay_server = {
- if self.relay_servers.is_empty() {
- "".to_owned()
- } else {
- let i = unsafe {
- ROTATION_RELAY_SERVER += 1;
- ROTATION_RELAY_SERVER % self.relay_servers.len()
- };
- self.relay_servers[i].clone()
+ if unsafe { ALWAYS_USE_RELAY } {
+ let relay_server = self.get_relay_server(addr.ip(), peer_addr.ip());
+ if !relay_server.is_empty() {
+ msg_out.set_request_relay(RequestRelay {
+ relay_server,
+ ..Default::default()
+ });
+ return Ok((msg_out, Some(peer_addr)));
}
- };
+ }
+ let same_intranet = !ws
+ && match peer_addr {
+ SocketAddr::V4(a) => match addr {
+ SocketAddr::V4(b) => a.ip() == b.ip(),
+ _ => false,
+ },
+ SocketAddr::V6(a) => match addr {
+ SocketAddr::V6(b) => a.ip() == b.ip(),
+ _ => false,
+ },
+ };
+ let socket_addr = AddrMangle::encode(addr);
+ let relay_server = self.get_relay_server(addr.ip(), peer_addr.ip());
if same_intranet {
log::debug!(
"Fetch local addr {:?} {:?} request from {:?}",
id,
- &peer.socket_addr,
- &addr
+ peer_addr,
+ addr
);
msg_out.set_fetch_local_addr(FetchLocalAddr {
socket_addr,
@@ -680,8 +710,8 @@ impl RendezvousServer {
log::debug!(
"Punch hole {:?} {:?} request from {:?}",
id,
- &peer.socket_addr,
- &addr
+ peer_addr,
+ addr
);
msg_out.set_punch_hole(PunchHole {
socket_addr,
@@ -690,7 +720,7 @@ impl RendezvousServer {
..Default::default()
});
}
- return Ok((msg_out, Some(peer.socket_addr)));
+ return Ok((msg_out, Some(peer_addr)));
} else {
let mut msg_out = RendezvousMessage::new();
msg_out.set_punch_hole_response(PunchHoleResponse {
@@ -702,13 +732,25 @@ impl RendezvousServer {
}
#[inline]
- async fn send_to_tcp(&mut self, msg: &RendezvousMessage, addr: SocketAddr) {
- let tcp = self.tcp_punch.lock().unwrap().remove(&addr);
- if let Some(mut tcp) = tcp {
+ async fn send_to_tcp(&mut self, msg: RendezvousMessage, addr: SocketAddr) {
+ let mut tcp = self.tcp_punch.lock().await.remove(&addr);
+ tokio::spawn(async move {
+ Self::send_to_sink(&mut tcp, msg).await;
+ });
+ }
+
+ #[inline]
+ async fn send_to_sink(sink: &mut Option<Sink>, msg: RendezvousMessage) {
+ if let Some(sink) = sink.as_mut() {
if let Ok(bytes) = msg.write_to_bytes() {
- tokio::spawn(async move {
- allow_err!(tcp.send(Bytes::from(bytes)).await);
- });
+ match sink {
+ Sink::TcpStream(s) => {
+ allow_err!(s.send(Bytes::from(bytes)).await);
+ }
+ Sink::Ws(ws) => {
+ allow_err!(ws.send(tungstenite::Message::Binary(bytes)).await);
+ }
+ }
}
}
}
@@ -716,15 +758,11 @@ impl RendezvousServer {
#[inline]
async fn send_to_tcp_sync(
&mut self,
- msg: &RendezvousMessage,
+ msg: RendezvousMessage,
addr: SocketAddr,
) -> ResultType<()> {
- let tcp = self.tcp_punch.lock().unwrap().remove(&addr);
- if let Some(mut tcp) = tcp {
- if let Ok(bytes) = msg.write_to_bytes() {
- tcp.send(Bytes::from(bytes)).await?;
- }
- }
+ let mut sink = self.tcp_punch.lock().await.remove(&addr);
+ Self::send_to_sink(&mut sink, msg).await;
Ok(())
}
@@ -734,12 +772,13 @@ impl RendezvousServer {
addr: SocketAddr,
ph: PunchHoleRequest,
key: &str,
+ ws: bool,
) -> ResultType<()> {
- let (msg, to_addr) = self.handle_punch_hole_request(addr, ph, key).await?;
+ let (msg, to_addr) = self.handle_punch_hole_request(addr, ph, key, ws).await?;
if let Some(addr) = to_addr {
- self.tx.send((msg, addr))?;
+ self.tx.send(Data::Msg(msg, addr))?;
} else {
- self.send_to_tcp_sync(&msg, addr).await?;
+ self.send_to_tcp_sync(msg, addr).await?;
}
Ok(())
}
@@ -751,8 +790,8 @@ impl RendezvousServer {
ph: PunchHoleRequest,
key: &str,
) -> ResultType<()> {
- let (msg, to_addr) = self.handle_punch_hole_request(addr, ph, key).await?;
- self.tx.send((
+ let (msg, to_addr) = self.handle_punch_hole_request(addr, ph, key, false).await?;
+ self.tx.send(Data::Msg(
msg,
match to_addr {
Some(addr) => addr,
@@ -761,16 +800,421 @@ impl RendezvousServer {
))?;
Ok(())
}
+
+ async fn check_ip_blocker(&self, ip: &str, id: &str) -> bool {
+ let mut lock = IP_BLOCKER.lock().await;
+ let now = Instant::now();
+ if let Some(old) = lock.get_mut(ip) {
+ let counter = &mut old.0;
+ if counter.1.elapsed().as_secs() > IP_BLOCK_DUR {
+ counter.0 = 0;
+ } else if counter.0 > 30 {
+ return false;
+ }
+ counter.0 += 1;
+ counter.1 = now;
+
+ let counter = &mut old.1;
+ let is_new = counter.0.get(id).is_none();
+ if counter.1.elapsed().as_secs() > DAY_SECONDS {
+ counter.0.clear();
+ } else if counter.0.len() > 300 {
+ return !is_new;
+ }
+ if is_new {
+ counter.0.insert(id.to_owned());
+ }
+ counter.1 = now;
+ } else {
+ lock.insert(ip.to_owned(), ((0, now), (Default::default(), now)));
+ }
+ true
+ }
+
+ fn parse_relay_servers(&mut self, relay_servers: &str) {
+ let rs = get_servers(relay_servers, "relay-servers");
+ self.relay_servers0 = Arc::new(rs);
+ self.relay_servers = self.relay_servers0.clone();
+ }
+
+ fn get_relay_server(&self, pa: IpAddr, pb: IpAddr) -> String {
+ if self.relay_servers.is_empty() {
+ return "".to_owned();
+ } else if self.relay_servers.len() == 1 {
+ return self.relay_servers[0].clone();
+ }
+ let i = unsafe {
+ ROTATION_RELAY_SERVER += 1;
+ ROTATION_RELAY_SERVER % self.relay_servers.len()
+ };
+ self.relay_servers[i].clone()
+ }
+
+ async fn check_cmd(&self, cmd: &str) -> String {
+ let mut res = "".to_owned();
+ let mut fds = cmd.trim().split(" ");
+ match fds.next() {
+ Some("h") => {
+ res = format!(
+ "{}\n{}\n{}\n{}\n{}\n{}\n",
+ "relay-servers(rs) <separated by ,>",
+ "reload-geo(rg)",
+ "ip-blocker(ib) [<ip>|<number>] [-]",
+ "ip-changes(ic) [<id>|<number>] [-]",
+ "always-use-relay(aur)",
+ "test-geo(tg) <ip1> <ip2>"
+ )
+ }
+ Some("relay-servers" | "rs") => {
+ if let Some(rs) = fds.next() {
+ self.tx.send(Data::RelayServers0(rs.to_owned())).ok();
+ } else {
+ for ip in self.relay_servers.iter() {
+ res += &format!("{}\n", ip);
+ }
+ }
+ }
+ Some("ip-blocker" | "ib") => {
+ let mut lock = IP_BLOCKER.lock().await;
+ lock.retain(|&_, (a, b)| {
+ a.1.elapsed().as_secs() <= IP_BLOCK_DUR
+ || b.1.elapsed().as_secs() <= DAY_SECONDS
+ });
+ res = format!("{}\n", lock.len());
+ let ip = fds.next();
+ let mut start = ip.map(|x| x.parse::<i32>().unwrap_or(-1)).unwrap_or(-1);
+ if start < 0 {
+ if let Some(ip) = ip {
+ if let Some((a, b)) = lock.get(ip) {
+ res += &format!(
+ "{}/{}s {}/{}s\n",
+ a.0,
+ a.1.elapsed().as_secs(),
+ b.0.len(),
+ b.1.elapsed().as_secs()
+ );
+ }
+ if fds.next() == Some("-") {
+ lock.remove(ip);
+ }
+ } else {
+ start = 0;
+ }
+ }
+ if start >= 0 {
+ let mut it = lock.iter();
+ for i in 0..(start + 10) {
+ let x = it.next();
+ if x.is_none() {
+ break;
+ }
+ if i < start {
+ continue;
+ }
+ if let Some((ip, (a, b))) = x {
+ res += &format!(
+ "{}: {}/{}s {}/{}s\n",
+ ip,
+ a.0,
+ a.1.elapsed().as_secs(),
+ b.0.len(),
+ b.1.elapsed().as_secs()
+ );
+ }
+ }
+ }
+ }
+ Some("ip-changes" | "ic") => {
+ let mut lock = IP_CHANGES.lock().await;
+ lock.retain(|&_, v| v.0.elapsed().as_secs() < IP_CHANGE_DUR_X2 && v.1.len() > 1);
+ res = format!("{}\n", lock.len());
+ let id = fds.next();
+ let mut start = id.map(|x| x.parse::<i32>().unwrap_or(-1)).unwrap_or(-1);
+ if start < 0 || start > 10_000_000 {
+ if let Some(id) = id {
+ if let Some((tm, ips)) = lock.get(id) {
+ res += &format!("{}s {:?}\n", tm.elapsed().as_secs(), ips);
+ }
+ if fds.next() == Some("-") {
+ lock.remove(id);
+ }
+ } else {
+ start = 0;
+ }
+ }
+ if start >= 0 {
+ let mut it = lock.iter();
+ for i in 0..(start + 10) {
+ let x = it.next();
+ if x.is_none() {
+ break;
+ }
+ if i < start {
+ continue;
+ }
+ if let Some((id, (tm, ips))) = x {
+ res += &format!("{}: {}s {:?}\n", id, tm.elapsed().as_secs(), ips,);
+ }
+ }
+ }
+ }
+ Some("always-use-relay" | "aur") => {
+ if let Some(rs) = fds.next() {
+ if rs.to_uppercase() == "Y" {
+ unsafe { ALWAYS_USE_RELAY = true };
+ } else {
+ unsafe { ALWAYS_USE_RELAY = false };
+ }
+ self.tx.send(Data::RelayServers0(rs.to_owned())).ok();
+ } else {
+ res += &format!("ALWAYS_USE_RELAY: {:?}\n", unsafe { ALWAYS_USE_RELAY });
+ }
+ }
+ Some("test-geo" | "tg") => {
+ if let Some(rs) = fds.next() {
+ if let Ok(a) = rs.parse::<IpAddr>() {
+ if let Some(rs) = fds.next() {
+ if let Ok(b) = rs.parse::<IpAddr>() {
+ res = format!("{:?}", self.get_relay_server(a, b));
+ }
+ } else {
+ res = format!("{:?}", self.get_relay_server(a, a));
+ }
+ }
+ }
+ }
+ _ => {}
+ }
+ res
+ }
+
+ async fn handle_listener2(&self, stream: TcpStream, addr: SocketAddr) {
+ if addr.ip().to_string() == "127.0.0.1" {
+ let rs = self.clone();
+ tokio::spawn(async move {
+ let mut stream = stream;
+ let mut buffer = [0; 64];
+ if let Ok(Ok(n)) = timeout(1000, stream.read(&mut buffer[..])).await {
+ if let Ok(data) = std::str::from_utf8(&buffer[..n]) {
+ let res = rs.check_cmd(data).await;
+ stream.write(res.as_bytes()).await.ok();
+ }
+ }
+ });
+ return;
+ }
+ let stream = FramedStream::from(stream, addr);
+ tokio::spawn(async move {
+ let mut stream = stream;
+ if let Some(Ok(bytes)) = stream.next_timeout(30_000).await {
+ if let Ok(msg_in) = RendezvousMessage::parse_from_bytes(&bytes) {
+ if let Some(rendezvous_message::Union::test_nat_request(_)) = msg_in.union {
+ let mut msg_out = RendezvousMessage::new();
+ msg_out.set_test_nat_response(TestNatResponse {
+ port: addr.port() as _,
+ ..Default::default()
+ });
+ stream.send(&msg_out).await.ok();
+ }
+ }
+ }
+ });
+ }
+
+ async fn handle_listener(
+ &self,
+ stream: TcpStream,
+ addr: SocketAddr,
+ key: &str,
+ id_change_support: bool,
+ ws: bool,
+ ) {
+ log::debug!("Tcp connection from {:?}, ws: {}", addr, ws);
+ let mut rs = self.clone();
+ let key = key.to_owned();
+ tokio::spawn(async move {
+ allow_err!(
+ rs.handle_listener_inner(stream, addr, &key, id_change_support, ws)
+ .await
+ );
+ });
+ }
+
+ #[inline]
+ async fn handle_listener_inner(
+ &mut self,
+ stream: TcpStream,
+ addr: SocketAddr,
+ key: &str,
+ id_change_support: bool,
+ ws: bool,
+ ) -> ResultType<()> {
+ let mut sink;
+ if ws {
+ let ws_stream = tokio_tungstenite::accept_async(stream).await?;
+ let (a, mut b) = ws_stream.split();
+ sink = Some(Sink::Ws(a));
+ while let Ok(Some(Ok(msg))) = timeout(30_000, b.next()).await {
+ match msg {
+ tungstenite::Message::Binary(bytes) => {
+ if !self
+ .handle_tcp(&bytes, &mut sink, addr, key, id_change_support, ws)
+ .await
+ {
+ break;
+ }
+ }
+ _ => {}
+ }
+ }
+ } else {
+ let (a, mut b) = Framed::new(stream, BytesCodec::new()).split();
+ sink = Some(Sink::TcpStream(a));
+ while let Ok(Some(Ok(bytes))) = timeout(30_000, b.next()).await {
+ if !self
+ .handle_tcp(&bytes, &mut sink, addr, key, id_change_support, ws)
+ .await
+ {
+ break;
+ }
+ }
+ }
+ if sink.is_none() {
+ self.tcp_punch.lock().await.remove(&addr);
+ }
+ log::debug!("Tcp connection from {:?} closed", addr);
+ Ok(())
+ }
+
+ #[inline]
+ async fn get_pk(&mut self, version: &str, id: String) -> Vec<u8> {
+ if version.is_empty() || self.sk.is_none() {
+ Vec::new()
+ } else {
+ match self.pm.get(&id).await {
+ Some(peer) => {
+ let pk = peer.read().await.pk.clone();
+ sign::sign(
+ &hbb_common::message_proto::IdPk {
+ id,
+ pk,
+ ..Default::default()
+ }
+ .write_to_bytes()
+ .unwrap_or_default(),
+ &self.sk.as_ref().unwrap(),
+ )
+ }
+ _ => Vec::new(),
+ }
+ }
+ }
+
+ #[inline]
+ fn get_server_sk(&mut self, key: &str) -> String {
+ let mut key = key.to_owned();
+ if let Ok(sk) = base64::decode(&key) {
+ if sk.len() == sign::SECRETKEYBYTES {
+ log::info!("The key is a crypto private key");
+ key = base64::encode(&sk[(sign::SECRETKEYBYTES / 2)..]);
+ let mut tmp = [0u8; sign::SECRETKEYBYTES];
+ tmp[..].copy_from_slice(&sk);
+ self.sk = Some(sign::SecretKey(tmp));
+ }
+ }
+
+ if key.is_empty() || key == "-" || key == "_" {
+ let (pk, sk) = crate::common::gen_sk();
+ self.sk = sk;
+ if !key.is_empty() {
+ key = pk;
+ } else {
+ std::env::set_var("KEY_FOR_API", pk);
+ }
+ }
+
+ if !key.is_empty() {
+ log::info!("Key: {}", key);
+ std::env::set_var("KEY_FOR_API", key.clone());
+ }
+ key
+ }
}
-pub fn test_if_valid_server(host: &str, name: &str) -> ResultType<SocketAddr> {
- let res = if host.contains(":") {
- hbb_common::to_socket_addr(host)
- } else {
- hbb_common::to_socket_addr(&format!("{}:{}", host, 0))
- };
- if res.is_err() {
- log::error!("Invalid {} {}: {:?}", name, host, res);
+async fn check_relay_servers(rs0: Arc<RelayServers>, tx: Sender) {
+ let mut futs = Vec::new();
+ let rs = Arc::new(Mutex::new(Vec::new()));
+ for x in rs0.iter() {
+ let mut host = x.to_owned();
+ if !host.contains(":") {
+ host = format!("{}:{}", host, hbb_common::config::RELAY_PORT);
+ }
+ let rs = rs.clone();
+ let x = x.clone();
+ futs.push(tokio::spawn(async move {
+ if FramedStream::new(&host, "0.0.0.0:0", CHECK_RELAY_TIMEOUT)
+ .await
+ .is_ok()
+ {
+ rs.lock().await.push(x);
+ }
+ }));
+ }
+ join_all(futs).await;
+ log::debug!("check_relay_servers");
+ let rs = std::mem::replace(&mut *rs.lock().await, Default::default());
+ if !rs.is_empty() {
+ tx.send(Data::RelayServers(rs)).ok();
}
- res
+}
+
+// temp solution to solve udp socket failure
+async fn test_hbbs(addr: SocketAddr) -> ResultType<()> {
+ let mut socket = FramedSocket::new("0.0.0.0:0").await?;
+ let mut msg_out = RendezvousMessage::new();
+ msg_out.set_register_peer(RegisterPeer {
+ id: "(:test_hbbs:)".to_owned(),
+ ..Default::default()
+ });
+ let mut last_time_recv = Instant::now();
+
+ let mut timer = interval(Duration::from_secs(1));
+ loop {
+ tokio::select! {
+ _ = timer.tick() => {
+ if last_time_recv.elapsed().as_secs() > 12 {
+ log::error!("Timeout of test_hbbs");
+ std::process::exit(1);
+ }
+ socket.send(&msg_out, addr).await?;
+ }
+ Some(Ok((bytes, _))) = socket.next() => {
+ if let Ok(msg_in) = RendezvousMessage::parse_from_bytes(&bytes) {
+ log::trace!("Recv {:?} of test_hbbs", msg_in);
+ last_time_recv = Instant::now();
+ }
+ }
+ }
+ }
+}
+
+#[inline]
+fn distance(a: &(i32, i32), b: &(i32, i32)) -> i32 {
+ let dx = a.0 - b.0;
+ let dy = a.1 - b.1;
+ dx * dx + dy * dy
+}
+
+#[inline]
+async fn send_rk_res(
+ socket: &mut FramedSocket,
+ addr: SocketAddr,
+ res: register_pk_response::Result,
+) -> ResultType<()> {
+ let mut msg_out = RendezvousMessage::new();
+ msg_out.set_register_pk_response(RegisterPkResponse {
+ result: res.into(),
+ ..Default::default()
+ });
+ socket.send(&msg_out, addr).await
}
diff --git a/src/sled_async.rs b/src/sled_async.rs
deleted file mode 100644
index cabbe12..0000000
--- a/src/sled_async.rs
+++ /dev/null
@@ -1,101 +0,0 @@
-use hbb_common::{
- allow_err, log,
- tokio::{self, sync::mpsc},
- ResultType,
-};
-use rocksdb::DB;
-
-#[derive(Debug)]
-enum Action {
- Insert((String, Vec<u8>)),
- Get((String, mpsc::Sender<Option<Vec<u8>>>)),
- _Close,
-}
-
-#[derive(Clone)]
-pub struct SledAsync {
- tx: Option<mpsc::UnboundedSender<Action>>,
- path: String,
-}
-
-impl SledAsync {
- pub fn new(path: &str, run: bool) -> ResultType<Self> {
- let mut res = Self {
- tx: None,
- path: path.to_owned(),
- };
- if run {
- res.run()?;
- }
- Ok(res)
- }
-
- pub fn run(&mut self) -> ResultType<std::thread::JoinHandle<()>> {
- let (tx, rx) = mpsc::unbounded_channel::<Action>();
- self.tx = Some(tx);
- let db = DB::open_default(&self.path)?;
- Ok(std::thread::spawn(move || {
- Self::io_loop(db, rx);
- log::debug!("Exit SledAsync loop");
- }))
- }
-
- #[tokio::main(basic_scheduler)]
- async fn io_loop(db: DB, rx: mpsc::UnboundedReceiver<Action>) {
- let mut rx = rx;
- while let Some(x) = rx.recv().await {
- match x {
- Action::Insert((key, value)) => {
- allow_err!(db.put(&key, &value));
- }
- Action::Get((key, sender)) => {
- let mut sender = sender;
- allow_err!(
- sender
- .send(if let Ok(v) = db.get(key) { v } else { None })
- .await
- );
- }
- Action::_Close => break,
- }
- }
- }
-
- pub fn _close(self, j: std::thread::JoinHandle<()>) {
- if let Some(tx) = &self.tx {
- allow_err!(tx.send(Action::_Close));
- }
- allow_err!(j.join());
- }
-
- pub async fn get(&mut self, key: String) -> Option<Vec<u8>> {
- if let Some(tx) = &self.tx {
- let (tx_once, mut rx) = mpsc::channel::<Option<Vec<u8>>>(1);
- allow_err!(tx.send(Action::Get((key, tx_once))));
- if let Some(v) = rx.recv().await {
- return v;
- }
- }
- None
- }
-
- #[inline]
- pub fn deserialize<'a, T: serde::Deserialize<'a>>(v: &'a Option<Vec<u8>>) -> Option<T> {
- if let Some(v) = v {
- if let Ok(v) = std::str::from_utf8(v) {
- if let Ok(v) = serde_json::from_str::<T>(&v) {
- return Some(v);
- }
- }
- }
- None
- }
-
- pub fn insert<T: serde::Serialize>(&mut self, key: String, v: T) {
- if let Some(tx) = &self.tx {
- if let Ok(v) = serde_json::to_vec(&v) {
- allow_err!(tx.send(Action::Insert((key, v))));
- }
- }
- }
-}
diff --git a/src/version.rs b/src/version.rs
new file mode 100644
index 0000000..75f232c
--- /dev/null
+++ b/src/version.rs
@@ -0,0 +1 @@
+pub const VERSION: &str = "1.1.5"; \ No newline at end of file