Compare commits
10 Commits
23296c6436
...
aa74585a1a
Author | SHA1 | Date | |
---|---|---|---|
aa74585a1a | |||
646afe2c40 | |||
77bc8364f2 | |||
ec9ab1d2bc | |||
bb81a32349 | |||
17b39dc6bc | |||
07fccb6b2a | |||
3a2367ef28 | |||
2116659a14 | |||
8404f38182 |
@ -1,4 +1,4 @@
|
|||||||
local executableName = 'fourth';
|
local executableName = 'l4p';
|
||||||
local build_image = 'img.kie.rs/jjkiers/rust-cross:rust1.71.1-zig';
|
local build_image = 'img.kie.rs/jjkiers/rust-cross:rust1.71.1-zig';
|
||||||
|
|
||||||
local archs = [
|
local archs = [
|
||||||
|
421
Cargo.lock
generated
421
Cargo.lock
generated
@ -19,22 +19,22 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aho-corasick"
|
name = "aho-corasick"
|
||||||
version = "1.1.1"
|
version = "1.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ea5d730647d4fadd988536d06fecce94b7b4f2a7efdae548f1cf4b63205518ab"
|
checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "atty"
|
name = "async-trait"
|
||||||
version = "0.2.14"
|
version = "0.1.77"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hermit-abi 0.1.19",
|
"proc-macro2",
|
||||||
"libc",
|
"quote",
|
||||||
"winapi",
|
"syn 2.0.50",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -78,12 +78,9 @@ checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.0.83"
|
version = "1.0.86"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
|
checksum = "7f9fa1897e4325be0d68d48df6aa1a71ac2ed4d27723887e7754192705350730"
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
@ -93,9 +90,12 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deranged"
|
name = "deranged"
|
||||||
version = "0.3.8"
|
version = "0.3.11"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946"
|
checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
|
||||||
|
dependencies = [
|
||||||
|
"powerfmt",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "enum_primitive"
|
name = "enum_primitive"
|
||||||
@ -108,12 +108,12 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "env_logger"
|
name = "env_logger"
|
||||||
version = "0.7.1"
|
version = "0.10.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36"
|
checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atty",
|
|
||||||
"humantime",
|
"humantime",
|
||||||
|
"is-terminal",
|
||||||
"log",
|
"log",
|
||||||
"regex",
|
"regex",
|
||||||
"termcolor",
|
"termcolor",
|
||||||
@ -127,35 +127,18 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "form_urlencoded"
|
name = "form_urlencoded"
|
||||||
version = "1.2.0"
|
version = "1.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652"
|
checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "fourth"
|
|
||||||
version = "0.1.7"
|
|
||||||
dependencies = [
|
|
||||||
"byte_string",
|
|
||||||
"bytes",
|
|
||||||
"futures",
|
|
||||||
"log",
|
|
||||||
"pretty_env_logger",
|
|
||||||
"serde",
|
|
||||||
"serde_yaml",
|
|
||||||
"time",
|
|
||||||
"tls-parser",
|
|
||||||
"tokio",
|
|
||||||
"url",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures"
|
name = "futures"
|
||||||
version = "0.3.28"
|
version = "0.3.30"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40"
|
checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
@ -168,9 +151,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-channel"
|
name = "futures-channel"
|
||||||
version = "0.3.28"
|
version = "0.3.30"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2"
|
checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-sink",
|
"futures-sink",
|
||||||
@ -178,15 +161,15 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-core"
|
name = "futures-core"
|
||||||
version = "0.3.28"
|
version = "0.3.30"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c"
|
checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-executor"
|
name = "futures-executor"
|
||||||
version = "0.3.28"
|
version = "0.3.30"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0"
|
checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-task",
|
"futures-task",
|
||||||
@ -195,38 +178,38 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-io"
|
name = "futures-io"
|
||||||
version = "0.3.28"
|
version = "0.3.30"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964"
|
checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-macro"
|
name = "futures-macro"
|
||||||
version = "0.3.28"
|
version = "0.3.30"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72"
|
checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.37",
|
"syn 2.0.50",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-sink"
|
name = "futures-sink"
|
||||||
version = "0.3.28"
|
version = "0.3.30"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e"
|
checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-task"
|
name = "futures-task"
|
||||||
version = "0.3.28"
|
version = "0.3.30"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65"
|
checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-util"
|
name = "futures-util"
|
||||||
version = "0.3.28"
|
version = "0.3.30"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533"
|
checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
@ -242,9 +225,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "getrandom"
|
name = "getrandom"
|
||||||
version = "0.2.10"
|
version = "0.2.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
|
checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"libc",
|
"libc",
|
||||||
@ -253,45 +236,33 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gimli"
|
name = "gimli"
|
||||||
version = "0.28.0"
|
version = "0.28.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0"
|
checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.14.1"
|
version = "0.14.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12"
|
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hermit-abi"
|
name = "hermit-abi"
|
||||||
version = "0.1.19"
|
version = "0.3.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
|
checksum = "bd5256b483761cd23699d0da46cc6fd2ee3be420bbe6d020ae4a091e70b7e9fd"
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "hermit-abi"
|
|
||||||
version = "0.3.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "humantime"
|
name = "humantime"
|
||||||
version = "1.3.0"
|
version = "2.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
|
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
||||||
dependencies = [
|
|
||||||
"quick-error",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "idna"
|
name = "idna"
|
||||||
version = "0.4.0"
|
version = "0.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c"
|
checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-bidi",
|
"unicode-bidi",
|
||||||
"unicode-normalization",
|
"unicode-normalization",
|
||||||
@ -299,31 +270,60 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indexmap"
|
name = "indexmap"
|
||||||
version = "2.0.2"
|
version = "2.2.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897"
|
checksum = "233cf39063f058ea2caae4091bf4a3ef70a653afbc026f5c4a4135d114e3c177"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"equivalent",
|
"equivalent",
|
||||||
"hashbrown",
|
"hashbrown",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "is-terminal"
|
||||||
version = "1.0.9"
|
version = "0.4.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
|
checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b"
|
||||||
|
dependencies = [
|
||||||
|
"hermit-abi",
|
||||||
|
"libc",
|
||||||
|
"windows-sys 0.52.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itoa"
|
||||||
|
version = "1.0.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "layer4-proxy"
|
||||||
|
version = "0.1.7"
|
||||||
|
dependencies = [
|
||||||
|
"async-trait",
|
||||||
|
"byte_string",
|
||||||
|
"bytes",
|
||||||
|
"futures",
|
||||||
|
"log",
|
||||||
|
"pretty_env_logger",
|
||||||
|
"serde",
|
||||||
|
"serde_yaml",
|
||||||
|
"time",
|
||||||
|
"tls-parser",
|
||||||
|
"tokio",
|
||||||
|
"url",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.148"
|
version = "0.2.153"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b"
|
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lock_api"
|
name = "lock_api"
|
||||||
version = "0.4.10"
|
version = "0.4.11"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16"
|
checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"scopeguard",
|
"scopeguard",
|
||||||
@ -337,9 +337,9 @@ checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.6.4"
|
version = "2.7.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
|
checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "minimal-lexical"
|
name = "minimal-lexical"
|
||||||
@ -349,22 +349,22 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "miniz_oxide"
|
name = "miniz_oxide"
|
||||||
version = "0.7.1"
|
version = "0.7.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7"
|
checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"adler",
|
"adler",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mio"
|
name = "mio"
|
||||||
version = "0.8.8"
|
version = "0.8.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2"
|
checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"wasi",
|
"wasi",
|
||||||
"windows-sys",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -399,20 +399,26 @@ dependencies = [
|
|||||||
"syn 1.0.109",
|
"syn 1.0.109",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-conv"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-traits"
|
name = "num-traits"
|
||||||
version = "0.1.43"
|
version = "0.1.43"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31"
|
checksum = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"num-traits 0.2.16",
|
"num-traits 0.2.18",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-traits"
|
name = "num-traits"
|
||||||
version = "0.2.16"
|
version = "0.2.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2"
|
checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
]
|
]
|
||||||
@ -423,24 +429,24 @@ version = "1.16.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
|
checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hermit-abi 0.3.3",
|
"hermit-abi",
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num_threads"
|
name = "num_threads"
|
||||||
version = "0.1.6"
|
version = "0.1.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44"
|
checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "object"
|
name = "object"
|
||||||
version = "0.32.1"
|
version = "0.32.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0"
|
checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
@ -457,22 +463,22 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parking_lot_core"
|
name = "parking_lot_core"
|
||||||
version = "0.9.8"
|
version = "0.9.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447"
|
checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"libc",
|
"libc",
|
||||||
"redox_syscall",
|
"redox_syscall",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"windows-targets",
|
"windows-targets 0.48.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "percent-encoding"
|
name = "percent-encoding"
|
||||||
version = "2.3.0"
|
version = "2.3.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94"
|
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "phf"
|
name = "phf"
|
||||||
@ -524,6 +530,12 @@ version = "0.1.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "powerfmt"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ppv-lite86"
|
name = "ppv-lite86"
|
||||||
version = "0.2.17"
|
version = "0.2.17"
|
||||||
@ -532,9 +544,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pretty_env_logger"
|
name = "pretty_env_logger"
|
||||||
version = "0.4.0"
|
version = "0.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "926d36b9553851b8b0005f1275891b392ee4d2d833852c417ed025477350fb9d"
|
checksum = "865724d4dbe39d9f3dd3b52b88d859d66bcb2d6a0acfd5ea68a65fb66d4bdc1c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"log",
|
"log",
|
||||||
@ -542,24 +554,18 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.67"
|
version = "1.0.78"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328"
|
checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "quick-error"
|
|
||||||
version = "1.2.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.33"
|
version = "1.0.35"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
|
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
@ -596,18 +602,18 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redox_syscall"
|
name = "redox_syscall"
|
||||||
version = "0.3.5"
|
version = "0.4.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
|
checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "1.9.6"
|
version = "1.10.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ebee201405406dbf528b8b672104ae6d6d63e6d118cb10e4d51abbc7b58044ff"
|
checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
"memchr",
|
"memchr",
|
||||||
@ -617,9 +623,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex-automata"
|
name = "regex-automata"
|
||||||
version = "0.3.9"
|
version = "0.4.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "59b23e92ee4318893fa3fe3e6fb365258efbfe6ac6ab30f090cdcbb7aa37efa9"
|
checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
"memchr",
|
"memchr",
|
||||||
@ -628,9 +634,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex-syntax"
|
name = "regex-syntax"
|
||||||
version = "0.7.5"
|
version = "0.8.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da"
|
checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc-demangle"
|
name = "rustc-demangle"
|
||||||
@ -655,9 +661,9 @@ checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ryu"
|
name = "ryu"
|
||||||
version = "1.0.15"
|
version = "1.0.17"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
|
checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scopeguard"
|
name = "scopeguard"
|
||||||
@ -667,29 +673,29 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.188"
|
version = "1.0.197"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e"
|
checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.188"
|
version = "1.0.197"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2"
|
checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.37",
|
"syn 2.0.50",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_yaml"
|
name = "serde_yaml"
|
||||||
version = "0.9.25"
|
version = "0.9.32"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1a49e178e4452f45cb61d0cd8cebc1b0fafd3e41929e996cef79aa3aca91f574"
|
checksum = "8fd075d994154d4a774f95b51fb96bdc2832b0ea48425c92546073816cda1f2f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"itoa",
|
"itoa",
|
||||||
@ -724,18 +730,18 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smallvec"
|
name = "smallvec"
|
||||||
version = "1.11.1"
|
version = "1.13.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a"
|
checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "socket2"
|
name = "socket2"
|
||||||
version = "0.5.4"
|
version = "0.5.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e"
|
checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"windows-sys",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -751,9 +757,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.37"
|
version = "2.0.50"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8"
|
checksum = "74f1bdc9872430ce9b75da68329d1c1746faf50ffac5f19e02b71e37ff881ffb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -762,23 +768,25 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "termcolor"
|
name = "termcolor"
|
||||||
version = "1.3.0"
|
version = "1.4.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6093bad37da69aab9d123a8091e4be0aa4a03e4d601ec641c327398315f62b64"
|
checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"winapi-util",
|
"winapi-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "time"
|
name = "time"
|
||||||
version = "0.3.29"
|
version = "0.3.34"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "426f806f4089c493dcac0d24c29c01e2c38baf8e30f1b716ee37e83d200b18fe"
|
checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"deranged",
|
"deranged",
|
||||||
"itoa",
|
"itoa",
|
||||||
"libc",
|
"libc",
|
||||||
|
"num-conv",
|
||||||
"num_threads",
|
"num_threads",
|
||||||
|
"powerfmt",
|
||||||
"serde",
|
"serde",
|
||||||
"time-core",
|
"time-core",
|
||||||
"time-macros",
|
"time-macros",
|
||||||
@ -792,10 +800,11 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "time-macros"
|
name = "time-macros"
|
||||||
version = "0.2.15"
|
version = "0.2.17"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20"
|
checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"num-conv",
|
||||||
"time-core",
|
"time-core",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -830,9 +839,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "1.32.0"
|
version = "1.36.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9"
|
checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"backtrace",
|
"backtrace",
|
||||||
"bytes",
|
"bytes",
|
||||||
@ -844,25 +853,25 @@ dependencies = [
|
|||||||
"signal-hook-registry",
|
"signal-hook-registry",
|
||||||
"socket2",
|
"socket2",
|
||||||
"tokio-macros",
|
"tokio-macros",
|
||||||
"windows-sys",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-macros"
|
name = "tokio-macros"
|
||||||
version = "2.1.0"
|
version = "2.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e"
|
checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.37",
|
"syn 2.0.50",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-bidi"
|
name = "unicode-bidi"
|
||||||
version = "0.3.13"
|
version = "0.3.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460"
|
checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
@ -872,24 +881,24 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-normalization"
|
name = "unicode-normalization"
|
||||||
version = "0.1.22"
|
version = "0.1.23"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
|
checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"tinyvec",
|
"tinyvec",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unsafe-libyaml"
|
name = "unsafe-libyaml"
|
||||||
version = "0.2.9"
|
version = "0.2.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f28467d3e1d3c6586d8f25fa243f544f5800fec42d97032474e17222c2b75cfa"
|
checksum = "ab4c90930b95a82d00dc9e9ac071b4991924390d46cbd0dfe566148667605e4b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "url"
|
name = "url"
|
||||||
version = "2.4.1"
|
version = "2.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5"
|
checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"form_urlencoded",
|
"form_urlencoded",
|
||||||
"idna",
|
"idna",
|
||||||
@ -939,7 +948,16 @@ version = "0.48.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-targets",
|
"windows-targets 0.48.5",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-sys"
|
||||||
|
version = "0.52.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||||
|
dependencies = [
|
||||||
|
"windows-targets 0.52.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -948,13 +966,28 @@ version = "0.48.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
|
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows_aarch64_gnullvm",
|
"windows_aarch64_gnullvm 0.48.5",
|
||||||
"windows_aarch64_msvc",
|
"windows_aarch64_msvc 0.48.5",
|
||||||
"windows_i686_gnu",
|
"windows_i686_gnu 0.48.5",
|
||||||
"windows_i686_msvc",
|
"windows_i686_msvc 0.48.5",
|
||||||
"windows_x86_64_gnu",
|
"windows_x86_64_gnu 0.48.5",
|
||||||
"windows_x86_64_gnullvm",
|
"windows_x86_64_gnullvm 0.48.5",
|
||||||
"windows_x86_64_msvc",
|
"windows_x86_64_msvc 0.48.5",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-targets"
|
||||||
|
version = "0.52.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d380ba1dc7187569a8a9e91ed34b8ccfc33123bbacb8c0aed2d1ad7f3ef2dc5f"
|
||||||
|
dependencies = [
|
||||||
|
"windows_aarch64_gnullvm 0.52.3",
|
||||||
|
"windows_aarch64_msvc 0.52.3",
|
||||||
|
"windows_i686_gnu 0.52.3",
|
||||||
|
"windows_i686_msvc 0.52.3",
|
||||||
|
"windows_x86_64_gnu 0.52.3",
|
||||||
|
"windows_x86_64_gnullvm 0.52.3",
|
||||||
|
"windows_x86_64_msvc 0.52.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -963,38 +996,80 @@ version = "0.48.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_gnullvm"
|
||||||
|
version = "0.52.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "68e5dcfb9413f53afd9c8f86e56a7b4d86d9a2fa26090ea2dc9e40fba56c6ec6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_aarch64_msvc"
|
name = "windows_aarch64_msvc"
|
||||||
version = "0.48.5"
|
version = "0.48.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_msvc"
|
||||||
|
version = "0.52.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8dab469ebbc45798319e69eebf92308e541ce46760b49b18c6b3fe5e8965b30f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_gnu"
|
name = "windows_i686_gnu"
|
||||||
version = "0.48.5"
|
version = "0.48.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_gnu"
|
||||||
|
version = "0.52.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2a4e9b6a7cac734a8b4138a4e1044eac3404d8326b6c0f939276560687a033fb"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_msvc"
|
name = "windows_i686_msvc"
|
||||||
version = "0.48.5"
|
version = "0.48.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_msvc"
|
||||||
|
version = "0.52.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "28b0ec9c422ca95ff34a78755cfa6ad4a51371da2a5ace67500cf7ca5f232c58"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_gnu"
|
name = "windows_x86_64_gnu"
|
||||||
version = "0.48.5"
|
version = "0.48.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnu"
|
||||||
|
version = "0.52.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "704131571ba93e89d7cd43482277d6632589b18ecf4468f591fbae0a8b101614"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_gnullvm"
|
name = "windows_x86_64_gnullvm"
|
||||||
version = "0.48.5"
|
version = "0.48.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnullvm"
|
||||||
|
version = "0.52.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "42079295511643151e98d61c38c0acc444e52dd42ab456f7ccfd5152e8ecf21c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_msvc"
|
name = "windows_x86_64_msvc"
|
||||||
version = "0.48.5"
|
version = "0.48.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_msvc"
|
||||||
|
version = "0.52.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0770833d60a970638e989b3fa9fd2bb1aaadcf88963d1659fd7d9990196ed2d6"
|
||||||
|
26
Cargo.toml
26
Cargo.toml
@ -1,13 +1,13 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "fourth"
|
name = "layer4-proxy"
|
||||||
version = "0.1.7"
|
version = "0.1.7"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
authors = ["LI Rui <lr_cn@outlook.com>"]
|
authors = ["Jacob Kiers <code@kiers.eu>"]
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
description = "Simple and fast layer 4 proxy in Rust"
|
description = "Simple and fast layer 4 proxy in Rust"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
homepage = "https://github.com/KernelErr/fourth"
|
homepage = "https://code.kiers.eu/jjkiers/layer4-proxy"
|
||||||
repository = "https://github.com/KernelErr/fourth"
|
repository = "https://code.kiers.eu/jjkiers/layer4-proxy"
|
||||||
keywords = ["proxy", "network"]
|
keywords = ["proxy", "network"]
|
||||||
categories = ["web-programming"]
|
categories = ["web-programming"]
|
||||||
|
|
||||||
@ -15,16 +15,20 @@ categories = ["web-programming"]
|
|||||||
|
|
||||||
exclude = [".*"]
|
exclude = [".*"]
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "l4p"
|
||||||
|
path = "src/main.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
async-trait = "0.1.73"
|
||||||
|
byte_string = "1"
|
||||||
|
bytes = "1.1"
|
||||||
|
futures = "0.3"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
pretty_env_logger = "0.4"
|
pretty_env_logger = "0.5"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_yaml = "0.9.21"
|
serde_yaml = "0.9.21"
|
||||||
futures = "0.3"
|
|
||||||
tls-parser = "0.11"
|
|
||||||
url = "2.2.2"
|
|
||||||
time = { version = "0.3.1", features = ["local-offset", "formatting"] }
|
time = { version = "0.3.1", features = ["local-offset", "formatting"] }
|
||||||
|
tls-parser = "0.11"
|
||||||
tokio = { version = "1.0", features = ["full"] }
|
tokio = { version = "1.0", features = ["full"] }
|
||||||
|
url = "2.2.2"
|
||||||
bytes = "1.1"
|
|
||||||
byte_string = "1"
|
|
||||||
|
80
README-ZH.md
80
README-ZH.md
@ -1,80 +0,0 @@
|
|||||||
# Fourth
|
|
||||||
|
|
||||||
> 这一波在第四层。
|
|
||||||
|
|
||||||
[![](https://img.shields.io/crates/v/fourth)](https://crates.io/crates/fourth) [![CI](https://img.shields.io/github/workflow/status/kernelerr/fourth/Rust)](https://github.com/KernelErr/fourth/actions/workflows/rust.yml)
|
|
||||||
|
|
||||||
[English](/README-EN.md)
|
|
||||||
|
|
||||||
**积极开发中,0.1版本迭代可能较快**
|
|
||||||
|
|
||||||
Fourth是一个Rust实现的Layer 4代理,用于监听指定端口TCP/KCP流量,并根据规则转发到指定目标(目前只支持TCP)。
|
|
||||||
|
|
||||||
## 功能
|
|
||||||
|
|
||||||
- 监听指定端口代理到本地或远端指定端口
|
|
||||||
- 监听指定端口,通过TLS ClientHello消息中的SNI进行分流
|
|
||||||
- 支持KCP入站(警告:未测试)
|
|
||||||
|
|
||||||
## 安装方法
|
|
||||||
|
|
||||||
为了确保获得您架构下的最佳性能,请考虑自行编译,首选需要确保您拥有[Rust工具链](https://rustup.rs/)。
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ cd fourth
|
|
||||||
$ cargo build --release
|
|
||||||
```
|
|
||||||
|
|
||||||
将在`target/release/fourth`生成二进制文件,您也可以使用`cargo install --path . `来安装二进制文件。
|
|
||||||
|
|
||||||
或者您也可以使用Cargo直接安装:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ cargo install fourth
|
|
||||||
```
|
|
||||||
|
|
||||||
或者您也可以直接从Release中下载二进制文件。
|
|
||||||
|
|
||||||
## 配置
|
|
||||||
|
|
||||||
Fourth使用yaml格式的配置文件,默认情况下会读取`/etc/fourth/config.yaml`,您也可以设置自定义路径到环境变量`FOURTH_CONFIG`,如下是一个最小有效配置:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
version: 1
|
|
||||||
log: info
|
|
||||||
|
|
||||||
servers:
|
|
||||||
proxy_server:
|
|
||||||
listen:
|
|
||||||
- "127.0.0.1:8081"
|
|
||||||
default: remote
|
|
||||||
|
|
||||||
upstream:
|
|
||||||
remote: "tcp://www.remote.example.com:8082" # proxy to remote address
|
|
||||||
```
|
|
||||||
|
|
||||||
内置两个的upstream:ban(立即中断连接)、echo(返回读到的数据)。更详细的配置可以参考[示例配置](./example-config.yaml)。
|
|
||||||
|
|
||||||
注意:[::]会默认同时绑定IPv4和IPv6。
|
|
||||||
|
|
||||||
## 性能测试
|
|
||||||
|
|
||||||
在4C2G的服务器上测试:
|
|
||||||
|
|
||||||
使用Fourth代理到Nginx(直连QPS 120000): ~70000req/s (测试命令:`wrk -t200 -c1000 -d120s --latency http://proxy-server:8081 `)
|
|
||||||
|
|
||||||
使用Fourth代理到本地iperf3:8Gbps
|
|
||||||
|
|
||||||
## io_uring?
|
|
||||||
|
|
||||||
尽管经过了很多尝试,我们发现目前一些Rust下面的io_uring实现存在问题,我们使用的io_uring库实现尽管在吞吐量上可以做到单线程20Gbps(相比之下Tokio仅有8Gbps),但在QPS上存在性能损失较大的问题。因此在有成熟的io_uring实现之前,我们仍然选择epoll。之后我们会持续关注相关进展。
|
|
||||||
|
|
||||||
可能以后会为Linux高内核版本的用户提供可选的io_uring加速。
|
|
||||||
|
|
||||||
## 感谢
|
|
||||||
|
|
||||||
- [tokio_kcp](https://github.com/Matrix-Zhang/tokio_kcp)
|
|
||||||
|
|
||||||
## 协议
|
|
||||||
|
|
||||||
Fourth以Apache-2.0协议开源。
|
|
36
README.md
36
README.md
@ -1,41 +1,39 @@
|
|||||||
# Fourth
|
# l4p
|
||||||
|
|
||||||
> Hey, now we are on level 4!
|
> Hey, now we are on level 4!
|
||||||
|
|
||||||
[![](https://img.shields.io/crates/v/fourth)](https://crates.io/crates/fourth) [![CI](https://img.shields.io/github/workflow/status/kernelerr/fourth/Rust)](https://github.com/KernelErr/fourth/actions/workflows/rust.yml)
|
![CI](https://drone-ci.kiers.eu/api/badges/jjkiers/layer4-proxy/status.svg)
|
||||||
|
|
||||||
**Under heavy development, version 0.1 may update frequently**
|
`l4p` is a layer 4 proxy implemented by Rust to listen on specific ports and transfer TCP/KCP data to remote addresses(only TCP) according to configuration.
|
||||||
|
|
||||||
Fourth is a layer 4 proxy implemented by Rust to listen on specific ports and transfer TCP/KCP data to remote addresses(only TCP) according to configuration.
|
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- Listen on specific port and proxy to local or remote port
|
- Listen on specific port and proxy to local or remote port
|
||||||
- SNI-based rule without terminating TLS connection
|
- SNI-based rule without terminating TLS connection
|
||||||
- Allow KCP inbound(warning: untested)
|
- DNS-based backend with periodic resolution
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
To gain best performance on your computer's architecture, please consider build the source code. First, you may need [Rust tool chain](https://rustup.rs/).
|
To gain best performance on your computer's architecture, please consider build the source code. First, you may need [Rust tool chain](https://rustup.rs/).
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ cd fourth
|
$ cd l4p
|
||||||
$ cargo build --release
|
$ cargo build --release
|
||||||
```
|
```
|
||||||
|
|
||||||
Binary file will be generated at `target/release/fourth`, or you can use `cargo install --path .` to install.
|
Binary file will be generated at `target/release/l4p`, or you can use `cargo install --path .` to install.
|
||||||
|
|
||||||
Or you can use Cargo to install Fourth:
|
Or you can use Cargo to install `l4p`:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ cargo install fourth
|
$ cargo install l4p
|
||||||
```
|
```
|
||||||
|
|
||||||
Or you can download binary file form the Release page.
|
Or you can download binary file form the Release page.
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
Fourth will read yaml format configuration file from `/etc/fourth/config.yaml`, and you can set custom path to environment variable `FOURTH_CONFIG`, here is an minimal viable example:
|
`l4p` will read yaml format configuration file from `/etc/l4p/l4p.yaml`, and you can set custom path to environment variable `L4P_CONFIG`, here is an minimal viable example:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
version: 1
|
version: 1
|
||||||
@ -51,20 +49,16 @@ upstream:
|
|||||||
remote: "tcp://www.remote.example.com:8082" # proxy to remote address
|
remote: "tcp://www.remote.example.com:8082" # proxy to remote address
|
||||||
```
|
```
|
||||||
|
|
||||||
Built-in two upstreams: ban(terminate connection immediately), echo. For detailed configuration, check [this example](./example-config.yaml).
|
There are two upstreams built in:
|
||||||
|
* Ban, which terminates the connection immediately
|
||||||
|
* Echo, which reflects back with the input
|
||||||
|
|
||||||
## Performance Benchmark
|
For detailed configuration, check [this example](./config.yaml.example).
|
||||||
|
|
||||||
Tested on 4C2G server:
|
|
||||||
|
|
||||||
Use fourth to proxy to Nginx(QPS of direct connection: ~120000): ~70000 req/s (Command: `wrk -t200 -c1000 -d120s --latency http://proxy-server:8081`)
|
|
||||||
|
|
||||||
Use fourth to proxy to local iperf3: 8Gbps
|
|
||||||
|
|
||||||
## Thanks
|
## Thanks
|
||||||
|
|
||||||
- [tokio_kcp](https://github.com/Matrix-Zhang/tokio_kcp)
|
- [`l4p`](https://crates.io/crates/`l4p`), of which this is a heavily modified fork.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
Fourth is available under terms of Apache-2.0.
|
`l4p` is available under terms of Apache-2.0.
|
@ -2,15 +2,20 @@ version: 1
|
|||||||
log: debug
|
log: debug
|
||||||
|
|
||||||
servers:
|
servers:
|
||||||
example_server:
|
first_server:
|
||||||
listen:
|
listen:
|
||||||
- "0.0.0.0:8443"
|
- "0.0.0.0:8443"
|
||||||
|
- "[::]:8443"
|
||||||
tls: true # Enable TLS features like SNI filtering
|
tls: true # Enable TLS features like SNI filtering
|
||||||
sni:
|
sni:
|
||||||
api.example.org: example-api
|
api.example.org: example-api
|
||||||
www.example.org: gh-proxy
|
www.example.org: proxy
|
||||||
default: ban
|
default: ban
|
||||||
|
|
||||||
|
second-server:
|
||||||
|
listen: [ "127.0.0.1:8080" ]
|
||||||
|
default: echo
|
||||||
|
|
||||||
upstream:
|
upstream:
|
||||||
proxy: "tcp://new-www.example.org:443" # Connect over IPv4 or IPv6 to new-www.example.org:443
|
proxy: "tcp://new-www.example.org:443" # Connect over IPv4 or IPv6 to new-www.example.org:443
|
||||||
example-api: "tcp6://api-v1.example.com:443" # Connect over IPv6 to api-v1.example.com:443
|
example-api: "tcp6://api-v1.example.com:443" # Connect over IPv6 to api-v1.example.com:443
|
||||||
|
51
fourth.service
Normal file
51
fourth.service
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Fourth - Layer 4 proxy
|
||||||
|
|
||||||
|
After=network-online.target
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=default.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
|
||||||
|
# Allow read-only access to the config directory
|
||||||
|
ReadOnlyPaths=/etc/fourth
|
||||||
|
# Path to the binary
|
||||||
|
ExecStart=/usr/local/bin/fourth
|
||||||
|
|
||||||
|
# Needs CAP_NET_BIND_SERVICE in order to bind to lower ports
|
||||||
|
# When using ports above 1024, these should be made empty
|
||||||
|
AmbientCapabilities=CAP_NET_BIND_SERVICE
|
||||||
|
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
|
||||||
|
|
||||||
|
# Run as a dynamic user
|
||||||
|
DynamicUser=yes
|
||||||
|
|
||||||
|
# Security
|
||||||
|
PrivateTmp=yes
|
||||||
|
PrivateDevices=yes
|
||||||
|
ProtectSystem=strict
|
||||||
|
ProtectHome=yes
|
||||||
|
SystemCallFilter=@basic-io @file-system @network-io @system-service
|
||||||
|
SystemCallFilter=~@privileged
|
||||||
|
SystemCallFilter=~@resources
|
||||||
|
NoNewPrivileges=yes
|
||||||
|
ProtectProc=invisible
|
||||||
|
RemoveIPC=yes
|
||||||
|
RestrictAddressFamilies=AF_INET AF_INET6
|
||||||
|
RestrictNamespaces=yes
|
||||||
|
ProtectHostname=yes
|
||||||
|
ProtectClock=yes
|
||||||
|
ProtectKernelModules=yes
|
||||||
|
ProtectKernelLogs=yes
|
||||||
|
ProtectControlGroups=yes
|
||||||
|
LockPersonality=yes
|
||||||
|
MemoryDenyWriteExecute=yes
|
||||||
|
RestrictRealtime=yes
|
||||||
|
ProcSubset=pid
|
||||||
|
UMask=0077
|
||||||
|
SystemCallArchitectures=native
|
||||||
|
RestrictSUIDSGID=yes
|
||||||
|
ProtectKernelTunables=yes
|
@ -1,20 +1,19 @@
|
|||||||
use crate::servers::upstream_address::UpstreamAddress;
|
use crate::upstreams::ProxyToUpstream;
|
||||||
|
use crate::upstreams::Upstream;
|
||||||
use log::{debug, warn};
|
use log::{debug, warn};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{Error as IOError, Read};
|
use std::io::{Error as IOError, Read};
|
||||||
use std::net::SocketAddr;
|
|
||||||
use tokio::sync::Mutex;
|
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Config {
|
pub struct ConfigV1 {
|
||||||
pub base: ParsedConfig,
|
pub base: ParsedConfigV1,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, Deserialize, Clone)]
|
#[derive(Debug, Default, Deserialize, Clone)]
|
||||||
pub struct ParsedConfig {
|
pub struct ParsedConfigV1 {
|
||||||
pub version: i32,
|
pub version: i32,
|
||||||
pub log: Option<String>,
|
pub log: Option<String>,
|
||||||
pub servers: HashMap<String, ServerConfig>,
|
pub servers: HashMap<String, ServerConfig>,
|
||||||
@ -37,36 +36,54 @@ pub struct ServerConfig {
|
|||||||
pub sni: Option<HashMap<String, String>>,
|
pub sni: Option<HashMap<String, String>>,
|
||||||
pub default: Option<String>,
|
pub default: Option<String>,
|
||||||
}
|
}
|
||||||
|
impl TryInto<ProxyToUpstream> for &str {
|
||||||
|
type Error = ConfigError;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize)]
|
fn try_into(self) -> Result<ProxyToUpstream, Self::Error> {
|
||||||
pub enum Upstream {
|
let upstream_url = match Url::parse(self) {
|
||||||
Ban,
|
Ok(url) => url,
|
||||||
Echo,
|
Err(_) => {
|
||||||
Proxy(ProxyToUpstream),
|
return Err(ConfigError::Custom(format!(
|
||||||
}
|
"Invalid upstream url {}",
|
||||||
|
self
|
||||||
#[derive(Debug, Default)]
|
)))
|
||||||
struct Addr(Mutex<UpstreamAddress>);
|
|
||||||
|
|
||||||
impl Clone for Addr {
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
tokio::task::block_in_place(|| Self(Mutex::new(self.0.blocking_lock().clone())))
|
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, Default)]
|
let upstream_host = match upstream_url.host_str() {
|
||||||
pub struct ProxyToUpstream {
|
Some(host) => host,
|
||||||
pub name: String,
|
None => {
|
||||||
pub addr: String,
|
return Err(ConfigError::Custom(format!(
|
||||||
pub protocol: String,
|
"Invalid upstream url {}",
|
||||||
#[serde(skip_deserializing)]
|
self
|
||||||
addresses: Addr,
|
)))
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
impl ProxyToUpstream {
|
let upstream_port = match upstream_url.port_or_known_default() {
|
||||||
pub async fn resolve_addresses(&self) -> std::io::Result<Vec<SocketAddr>> {
|
Some(port) => port,
|
||||||
let mut addr = self.addresses.0.lock().await;
|
None => {
|
||||||
addr.resolve((*self.protocol).into()).await
|
return Err(ConfigError::Custom(format!(
|
||||||
|
"Invalid upstream url {}",
|
||||||
|
self
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
match upstream_url.scheme() {
|
||||||
|
"tcp" | "tcp4" | "tcp6" => {}
|
||||||
|
_ => {
|
||||||
|
return Err(ConfigError::Custom(format!(
|
||||||
|
"Invalid upstream scheme {}",
|
||||||
|
self
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(ProxyToUpstream::new(
|
||||||
|
format!("{}:{}", upstream_host, upstream_port),
|
||||||
|
upstream_url.scheme().to_string(),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,18 +94,18 @@ pub enum ConfigError {
|
|||||||
Custom(String),
|
Custom(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Config {
|
impl ConfigV1 {
|
||||||
pub fn new(path: &str) -> Result<Config, ConfigError> {
|
pub fn new(path: &str) -> Result<ConfigV1, ConfigError> {
|
||||||
let base = (load_config(path))?;
|
let base = load_config(path)?;
|
||||||
|
|
||||||
Ok(Config { base })
|
Ok(ConfigV1 { base })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_config(path: &str) -> Result<ParsedConfig, ConfigError> {
|
fn load_config(path: &str) -> Result<ParsedConfigV1, ConfigError> {
|
||||||
let mut contents = String::new();
|
let mut contents = String::new();
|
||||||
let mut file = (File::open(path))?;
|
let mut file = File::open(path)?;
|
||||||
(file.read_to_string(&mut contents))?;
|
file.read_to_string(&mut contents)?;
|
||||||
|
|
||||||
let base: BaseConfig = serde_yaml::from_str(&contents)?;
|
let base: BaseConfig = serde_yaml::from_str(&contents)?;
|
||||||
|
|
||||||
@ -109,64 +126,15 @@ fn load_config(path: &str) -> Result<ParsedConfig, ConfigError> {
|
|||||||
|
|
||||||
let mut parsed_upstream: HashMap<String, Upstream> = HashMap::new();
|
let mut parsed_upstream: HashMap<String, Upstream> = HashMap::new();
|
||||||
|
|
||||||
for (name, upstream) in base.upstream.iter() {
|
|
||||||
let upstream_url = match Url::parse(upstream) {
|
|
||||||
Ok(url) => url,
|
|
||||||
Err(_) => {
|
|
||||||
return Err(ConfigError::Custom(format!(
|
|
||||||
"Invalid upstream url {}",
|
|
||||||
upstream
|
|
||||||
)))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let upstream_host = match upstream_url.host_str() {
|
|
||||||
Some(host) => host,
|
|
||||||
None => {
|
|
||||||
return Err(ConfigError::Custom(format!(
|
|
||||||
"Invalid upstream url {}",
|
|
||||||
upstream
|
|
||||||
)))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let upstream_port = match upstream_url.port_or_known_default() {
|
|
||||||
Some(port) => port,
|
|
||||||
None => {
|
|
||||||
return Err(ConfigError::Custom(format!(
|
|
||||||
"Invalid upstream url {}",
|
|
||||||
upstream
|
|
||||||
)))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
match upstream_url.scheme() {
|
|
||||||
"tcp" | "tcp4" | "tcp6" => {}
|
|
||||||
_ => {
|
|
||||||
return Err(ConfigError::Custom(format!(
|
|
||||||
"Invalid upstream scheme {}",
|
|
||||||
upstream
|
|
||||||
)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let addr = UpstreamAddress::new(format!("{}:{}", upstream_host, upstream_port));
|
|
||||||
parsed_upstream.insert(
|
|
||||||
name.to_string(),
|
|
||||||
Upstream::Proxy(ProxyToUpstream {
|
|
||||||
name: name.to_string(),
|
|
||||||
addr: format!("{}:{}", upstream_host, upstream_port),
|
|
||||||
protocol: upstream_url.scheme().to_string(),
|
|
||||||
addresses: Addr(Mutex::new(addr)),
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
parsed_upstream.insert("ban".to_string(), Upstream::Ban);
|
parsed_upstream.insert("ban".to_string(), Upstream::Ban);
|
||||||
|
|
||||||
parsed_upstream.insert("echo".to_string(), Upstream::Echo);
|
parsed_upstream.insert("echo".to_string(), Upstream::Echo);
|
||||||
|
|
||||||
let parsed = ParsedConfig {
|
for (name, upstream) in base.upstream.iter() {
|
||||||
|
let ups = upstream.as_str().try_into()?;
|
||||||
|
parsed_upstream.insert(name.to_string(), Upstream::Proxy(ups));
|
||||||
|
}
|
||||||
|
|
||||||
|
let parsed = ParsedConfigV1 {
|
||||||
version: base.version,
|
version: base.version,
|
||||||
log: base.log,
|
log: base.log,
|
||||||
servers: base.servers,
|
servers: base.servers,
|
||||||
@ -176,7 +144,7 @@ fn load_config(path: &str) -> Result<ParsedConfig, ConfigError> {
|
|||||||
verify_config(parsed)
|
verify_config(parsed)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verify_config(config: ParsedConfig) -> Result<ParsedConfig, ConfigError> {
|
fn verify_config(config: ParsedConfigV1) -> Result<ParsedConfigV1, ConfigError> {
|
||||||
let mut used_upstreams: HashSet<String> = HashSet::new();
|
let mut used_upstreams: HashSet<String> = HashSet::new();
|
||||||
let mut upstream_names: HashSet<String> = HashSet::new();
|
let mut upstream_names: HashSet<String> = HashSet::new();
|
||||||
let mut listen_addresses: HashSet<String> = HashSet::new();
|
let mut listen_addresses: HashSet<String> = HashSet::new();
|
||||||
@ -250,7 +218,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_load_config() {
|
fn test_load_config() {
|
||||||
let config = Config::new("tests/config.yaml").unwrap();
|
let config = ConfigV1::new("tests/config.yaml").unwrap();
|
||||||
assert_eq!(config.base.version, 1);
|
assert_eq!(config.base.version, 1);
|
||||||
assert_eq!(config.base.log.unwrap(), "disable");
|
assert_eq!(config.base.log.unwrap(), "disable");
|
||||||
assert_eq!(config.base.servers.len(), 5);
|
assert_eq!(config.base.servers.len(), 5);
|
3
src/config/mod.rs
Normal file
3
src/config/mod.rs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
mod config;
|
||||||
|
pub(crate) use config::ConfigV1;
|
||||||
|
pub(crate) use config::ParsedConfigV1;
|
48
src/main.rs
48
src/main.rs
@ -1,18 +1,27 @@
|
|||||||
mod config;
|
mod config;
|
||||||
mod plugins;
|
mod plugins;
|
||||||
mod servers;
|
mod servers;
|
||||||
|
mod upstreams;
|
||||||
|
|
||||||
use crate::config::Config;
|
use crate::config::ConfigV1;
|
||||||
use crate::servers::Server;
|
use crate::servers::Server;
|
||||||
|
|
||||||
use log::{debug, error};
|
use log::{debug, error};
|
||||||
use std::env;
|
use std::path::PathBuf;
|
||||||
use std::path::Path;
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let config_path = find_config();
|
let config_path = match find_config() {
|
||||||
|
Ok(p) => p,
|
||||||
|
Err(paths) => {
|
||||||
|
println!("Could not find config file. Tried paths:");
|
||||||
|
for p in paths {
|
||||||
|
println!("- {}", p);
|
||||||
|
}
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let config = match Config::new(&config_path) {
|
let config = match ConfigV1::new(&config_path) {
|
||||||
Ok(config) => config,
|
Ok(config) => config,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
println!("Could not load config: {:?}", e);
|
println!("Could not load config: {:?}", e);
|
||||||
@ -21,24 +30,35 @@ fn main() {
|
|||||||
};
|
};
|
||||||
debug!("{:?}", config);
|
debug!("{:?}", config);
|
||||||
|
|
||||||
let mut server = Server::new(config.base);
|
let mut server = Server::new_from_v1_config(config.base);
|
||||||
debug!("{:?}", server);
|
debug!("{:?}", server);
|
||||||
|
|
||||||
let _ = server.run();
|
let _ = server.run();
|
||||||
error!("Server ended with errors");
|
error!("Server ended with errors");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_config() -> String {
|
fn find_config() -> Result<String, Vec<String>> {
|
||||||
let config_path =
|
let possible_paths = ["/etc/l4p", ""];
|
||||||
env::var("FOURTH_CONFIG").unwrap_or_else(|_| "/etc/fourth/config.yaml".to_string());
|
let possible_names = ["l4p.yaml", "config.yaml"];
|
||||||
|
|
||||||
if Path::new(&config_path).exists() {
|
let mut tried_paths = Vec::<String>::new();
|
||||||
return config_path;
|
|
||||||
|
for path in possible_paths
|
||||||
|
.iter()
|
||||||
|
.flat_map(|&path| {
|
||||||
|
possible_names
|
||||||
|
.iter()
|
||||||
|
.map(move |&file| PathBuf::new().join(path).join(file))
|
||||||
|
})
|
||||||
|
.collect::<Vec<PathBuf>>()
|
||||||
|
{
|
||||||
|
let path_str = path.to_string_lossy().to_string();
|
||||||
|
if path.exists() {
|
||||||
|
return Ok(path_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
if Path::new("config.yaml").exists() {
|
tried_paths.push(path_str);
|
||||||
return String::from("config.yaml");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String::from("")
|
Err(tried_paths)
|
||||||
}
|
}
|
||||||
|
@ -2,14 +2,14 @@ use log::{error, info};
|
|||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tokio::io;
|
|
||||||
use tokio::io::{AsyncRead, AsyncWrite, AsyncWriteExt};
|
|
||||||
use tokio::task::JoinHandle;
|
use tokio::task::JoinHandle;
|
||||||
|
|
||||||
mod protocol;
|
mod protocol;
|
||||||
pub(crate) mod upstream_address;
|
pub(crate) mod upstream_address;
|
||||||
|
|
||||||
use crate::config::{ParsedConfig, Upstream};
|
use crate::config::ParsedConfigV1;
|
||||||
|
use crate::upstreams::Upstream;
|
||||||
use protocol::tcp;
|
use protocol::tcp;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -29,7 +29,7 @@ pub(crate) struct Proxy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Server {
|
impl Server {
|
||||||
pub fn new(config: ParsedConfig) -> Self {
|
pub fn new_from_v1_config(config: ParsedConfigV1) -> Self {
|
||||||
let mut new_server = Server {
|
let mut new_server = Server {
|
||||||
proxies: Vec::new(),
|
proxies: Vec::new(),
|
||||||
};
|
};
|
||||||
@ -84,19 +84,7 @@ impl Server {
|
|||||||
);
|
);
|
||||||
let handle = tokio::spawn(async move {
|
let handle = tokio::spawn(async move {
|
||||||
match config.protocol.as_ref() {
|
match config.protocol.as_ref() {
|
||||||
"tcp" => {
|
"tcp" | "tcp4" | "tcp6" => {
|
||||||
let res = tcp::proxy(config.clone()).await;
|
|
||||||
if res.is_err() {
|
|
||||||
error!("Failed to start {}: {}", config.name, res.err().unwrap());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"tcp4" => {
|
|
||||||
let res = tcp::proxy(config.clone()).await;
|
|
||||||
if res.is_err() {
|
|
||||||
error!("Failed to start {}: {}", config.name, res.err().unwrap());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"tcp6" => {
|
|
||||||
let res = tcp::proxy(config.clone()).await;
|
let res = tcp::proxy(config.clone()).await;
|
||||||
if res.is_err() {
|
if res.is_err() {
|
||||||
error!("Failed to start {}: {}", config.name, res.err().unwrap());
|
error!("Failed to start {}: {}", config.name, res.err().unwrap());
|
||||||
@ -155,9 +143,9 @@ mod tests {
|
|||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_proxy() {
|
async fn test_proxy() {
|
||||||
use crate::config::Config;
|
use crate::config::ConfigV1;
|
||||||
let config = Config::new("tests/config.yaml").unwrap();
|
let config = ConfigV1::new("tests/config.yaml").unwrap();
|
||||||
let mut server = Server::new(config.base);
|
let mut server = Server::new_from_v1_config(config.base);
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
tcp_mock_server();
|
tcp_mock_server();
|
||||||
});
|
});
|
||||||
@ -212,17 +200,3 @@ mod tests {
|
|||||||
// conn.shutdown().await.unwrap();
|
// conn.shutdown().await.unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn copy<'a, R, W>(reader: &'a mut R, writer: &'a mut W) -> io::Result<u64>
|
|
||||||
where
|
|
||||||
R: AsyncRead + Unpin + ?Sized,
|
|
||||||
W: AsyncWrite + Unpin + ?Sized,
|
|
||||||
{
|
|
||||||
match io::copy(reader, writer).await {
|
|
||||||
Ok(u64) => {
|
|
||||||
let _ = writer.shutdown().await;
|
|
||||||
Ok(u64)
|
|
||||||
}
|
|
||||||
Err(_) => Ok(0),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,14 +1,11 @@
|
|||||||
use crate::config::Upstream;
|
|
||||||
use crate::servers::protocol::tls::get_sni;
|
use crate::servers::protocol::tls::get_sni;
|
||||||
use crate::servers::{copy, Proxy};
|
use crate::servers::Proxy;
|
||||||
use futures::future::try_join;
|
|
||||||
use log::{debug, error, info, warn};
|
use log::{debug, error, info, warn};
|
||||||
|
use std::error::Error;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tokio::io;
|
|
||||||
use tokio::io::AsyncWriteExt;
|
|
||||||
use tokio::net::{TcpListener, TcpStream};
|
use tokio::net::{TcpListener, TcpStream};
|
||||||
|
|
||||||
pub(crate) async fn proxy(config: Arc<Proxy>) -> Result<(), Box<dyn std::error::Error>> {
|
pub(crate) async fn proxy(config: Arc<Proxy>) -> Result<(), Box<dyn Error>> {
|
||||||
let listener = TcpListener::bind(config.listen).await?;
|
let listener = TcpListener::bind(config.listen).await?;
|
||||||
let config = config.clone();
|
let config = config.clone();
|
||||||
|
|
||||||
@ -33,7 +30,7 @@ pub(crate) async fn proxy(config: Arc<Proxy>) -> Result<(), Box<dyn std::error::
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn accept(inbound: TcpStream, proxy: Arc<Proxy>) -> Result<(), Box<dyn std::error::Error>> {
|
async fn accept(inbound: TcpStream, proxy: Arc<Proxy>) -> Result<(), Box<dyn Error>> {
|
||||||
info!("New connection from {:?}", inbound.peer_addr()?);
|
info!("New connection from {:?}", inbound.peer_addr()?);
|
||||||
|
|
||||||
let upstream_name = match proxy.tls {
|
let upstream_name = match proxy.tls {
|
||||||
@ -72,51 +69,9 @@ async fn accept(inbound: TcpStream, proxy: Arc<Proxy>) -> Result<(), Box<dyn std
|
|||||||
"No upstream named {:?} on server {:?}",
|
"No upstream named {:?} on server {:?}",
|
||||||
proxy.default_action, proxy.name
|
proxy.default_action, proxy.name
|
||||||
);
|
);
|
||||||
return process(inbound, proxy.upstream.get(&proxy.default_action).unwrap()).await;
|
proxy.upstream.get(&proxy.default_action).unwrap()
|
||||||
// ToDo: Remove unwrap and check default option
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
process(inbound, upstream).await
|
upstream.process(inbound).await
|
||||||
}
|
|
||||||
|
|
||||||
async fn process(
|
|
||||||
mut inbound: TcpStream,
|
|
||||||
upstream: &Upstream,
|
|
||||||
) -> Result<(), Box<dyn std::error::Error>> {
|
|
||||||
match upstream {
|
|
||||||
Upstream::Ban => {
|
|
||||||
inbound.shutdown().await?;
|
|
||||||
}
|
|
||||||
Upstream::Echo => {
|
|
||||||
let (mut ri, mut wi) = io::split(inbound);
|
|
||||||
let inbound_to_inbound = copy(&mut ri, &mut wi);
|
|
||||||
let bytes_tx = inbound_to_inbound.await;
|
|
||||||
debug!("Bytes read: {:?}", bytes_tx);
|
|
||||||
}
|
|
||||||
Upstream::Proxy(config) => {
|
|
||||||
let outbound = match config.protocol.as_ref() {
|
|
||||||
"tcp4" | "tcp6" | "tcp" => {
|
|
||||||
TcpStream::connect(config.resolve_addresses().await?.as_slice()).await?
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
error!("Reached unknown protocol: {:?}", config.protocol);
|
|
||||||
return Err("Reached unknown protocol".into());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
debug!("Connected to {:?}", outbound.peer_addr().unwrap());
|
|
||||||
|
|
||||||
let (mut ri, mut wi) = io::split(inbound);
|
|
||||||
let (mut ro, mut wo) = io::split(outbound);
|
|
||||||
|
|
||||||
let inbound_to_outbound = copy(&mut ri, &mut wo);
|
|
||||||
let outbound_to_inbound = copy(&mut ro, &mut wi);
|
|
||||||
|
|
||||||
let (bytes_tx, bytes_rx) = try_join(inbound_to_outbound, outbound_to_inbound).await?;
|
|
||||||
|
|
||||||
debug!("Bytes read: {:?} write: {:?}", bytes_tx, bytes_rx);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
@ -99,6 +99,6 @@ mod tests {
|
|||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
];
|
];
|
||||||
let sni = get_sni(&BUF);
|
let sni = get_sni(&BUF);
|
||||||
assert!(sni[0] == "www.lirui.tech".to_string());
|
assert!(sni[0] == *"www.lirui.tech");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ impl UpstreamAddress {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn is_resolved(&self) -> bool {
|
fn is_resolved(&self) -> bool {
|
||||||
self.resolved_addresses.len() > 0
|
!self.resolved_addresses.is_empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn time_remaining(&self) -> Duration {
|
fn time_remaining(&self) -> Duration {
|
||||||
|
51
src/upstreams/mod.rs
Normal file
51
src/upstreams/mod.rs
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
mod proxy_to_upstream;
|
||||||
|
|
||||||
|
use log::debug;
|
||||||
|
use serde::Deserialize;
|
||||||
|
use std::error::Error;
|
||||||
|
use tokio::io;
|
||||||
|
use tokio::io::{AsyncRead, AsyncWrite, AsyncWriteExt};
|
||||||
|
use tokio::net::TcpStream;
|
||||||
|
|
||||||
|
pub use crate::upstreams::proxy_to_upstream::ProxyToUpstream;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
|
pub enum Upstream {
|
||||||
|
Ban,
|
||||||
|
Echo,
|
||||||
|
Proxy(ProxyToUpstream),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Upstream {
|
||||||
|
pub(crate) async fn process(&self, mut inbound: TcpStream) -> Result<(), Box<dyn Error>> {
|
||||||
|
match self {
|
||||||
|
Upstream::Ban => {
|
||||||
|
inbound.shutdown().await?;
|
||||||
|
}
|
||||||
|
Upstream::Echo => {
|
||||||
|
let (mut ri, mut wi) = io::split(inbound);
|
||||||
|
let inbound_to_inbound = copy(&mut ri, &mut wi);
|
||||||
|
let bytes_tx = inbound_to_inbound.await;
|
||||||
|
debug!("Bytes read: {:?}", bytes_tx);
|
||||||
|
}
|
||||||
|
Upstream::Proxy(config) => {
|
||||||
|
config.proxy(inbound).await?;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn copy<'a, R, W>(reader: &'a mut R, writer: &'a mut W) -> io::Result<u64>
|
||||||
|
where
|
||||||
|
R: AsyncRead + Unpin + ?Sized,
|
||||||
|
W: AsyncWrite + Unpin + ?Sized,
|
||||||
|
{
|
||||||
|
match io::copy(reader, writer).await {
|
||||||
|
Ok(u64) => {
|
||||||
|
let _ = writer.shutdown().await;
|
||||||
|
Ok(u64)
|
||||||
|
}
|
||||||
|
Err(_) => Ok(0),
|
||||||
|
}
|
||||||
|
}
|
68
src/upstreams/proxy_to_upstream.rs
Normal file
68
src/upstreams/proxy_to_upstream.rs
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
use crate::servers::upstream_address::UpstreamAddress;
|
||||||
|
|
||||||
|
use crate::upstreams::copy;
|
||||||
|
use futures::future::try_join;
|
||||||
|
use log::{debug, error};
|
||||||
|
use serde::Deserialize;
|
||||||
|
use std::net::SocketAddr;
|
||||||
|
use tokio::io;
|
||||||
|
use tokio::net::TcpStream;
|
||||||
|
use tokio::sync::Mutex;
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
struct Addr(Mutex<UpstreamAddress>);
|
||||||
|
|
||||||
|
impl Clone for Addr {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
tokio::task::block_in_place(|| Self(Mutex::new(self.0.blocking_lock().clone())))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Deserialize, Default)]
|
||||||
|
pub struct ProxyToUpstream {
|
||||||
|
pub addr: String,
|
||||||
|
pub protocol: String,
|
||||||
|
#[serde(skip_deserializing)]
|
||||||
|
addresses: Addr,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ProxyToUpstream {
|
||||||
|
pub async fn resolve_addresses(&self) -> std::io::Result<Vec<SocketAddr>> {
|
||||||
|
let mut addr = self.addresses.0.lock().await;
|
||||||
|
addr.resolve((*self.protocol).into()).await
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new(address: String, protocol: String) -> Self {
|
||||||
|
Self {
|
||||||
|
addr: address.clone(),
|
||||||
|
protocol,
|
||||||
|
addresses: Addr(Mutex::new(UpstreamAddress::new(address))),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn proxy(&self, inbound: TcpStream) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let outbound = match self.protocol.as_ref() {
|
||||||
|
"tcp4" | "tcp6" | "tcp" => {
|
||||||
|
TcpStream::connect(self.resolve_addresses().await?.as_slice()).await?
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
error!("Reached unknown protocol: {:?}", self.protocol);
|
||||||
|
return Err("Reached unknown protocol".into());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
debug!("Connected to {:?}", outbound.peer_addr().unwrap());
|
||||||
|
|
||||||
|
let (mut ri, mut wi) = io::split(inbound);
|
||||||
|
let (mut ro, mut wo) = io::split(outbound);
|
||||||
|
|
||||||
|
let inbound_to_outbound = copy(&mut ri, &mut wo);
|
||||||
|
let outbound_to_inbound = copy(&mut ro, &mut wi);
|
||||||
|
|
||||||
|
let (bytes_tx, bytes_rx) = try_join(inbound_to_outbound, outbound_to_inbound).await?;
|
||||||
|
|
||||||
|
debug!("Bytes read: {:?} write: {:?}", bytes_tx, bytes_rx);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user