Compare commits

...
42 Commits
Author SHA1 Message Date
lbl8603 e73ed238cd 去除无用代码 2024-04-30 23:34:17 +08:00
lbl8603 c6c1d297af 去除多余代码 2024-04-30 23:28:45 +08:00
lbl8603 f78f8de15e 修改结构体名称 2024-04-30 23:25:40 +08:00
lbl8603 fcbc52dc2e 增加icmp代理日志 2024-04-30 23:24:12 +08:00
lbl8603 bbfa255dd3 优化环路检测逻辑 2024-04-29 23:23:28 +08:00
lbl8603 18fcee52db 兼容安卓icmp 2024-04-28 23:17:45 +08:00
lbl8603 d36d0b9491 增加编译目标 2024-04-28 23:17:33 +08:00
lbl8603 fb8d7ec5b8 调整解析地址选择 2024-04-25 23:34:44 +08:00
lbl8603 24341808ef Merge remote-tracking branch 'origin/2024-04-19' into 2024-04-19 2024-04-25 23:17:55 +08:00
lbl8603 353809f91c 优化路由添加逻辑 2024-04-25 20:04:32 +08:00
lbl8603 d2b2dfbf1e 去除多余校验 2024-04-25 19:44:20 +08:00
lbl8603 e027cf9d98 提交Cargo.lock锁定依赖版本 2024-04-24 23:18:05 +08:00
lbl8603 484b1657e8 修改dns参数描述 2024-04-24 23:09:20 +08:00
lbl8603 7dc4161f2f 避免打洞环路 2024-04-24 23:04:01 +08:00
lbl8603 18eb4af016 修改默认版本设置 2024-04-24 23:03:50 +08:00
lbl8603 635ec315f7 增加udp代理日志 2024-04-24 23:02:34 +08:00
lbl8603 37eb9ec045 优化dns查询 2024-04-24 23:02:01 +08:00
lbl8603 7c799589df 调整stun逻辑 2024-04-24 23:01:40 +08:00
lubeilin 4f52d58d6e 调整错误输出 2024-04-23 14:04:32 +08:00
lubeilin 441e374563 jni设置dns 2024-04-23 13:56:25 +08:00
lubeilin 3272f3cdca 设置dns 2024-04-23 12:40:33 +08:00
lbl8603 5b40a9f147 支持指定dns 2024-04-23 08:21:01 +08:00
lubeilin 12d4fc8e98 dns解析 2024-04-22 19:00:05 +08:00
lbl8603 ca74827aaf 拒绝服务端密钥对变化 2024-04-21 22:14:56 +08:00
lbl8603 0b570130e8 处理tcp加密注册失败的问题 2024-04-21 18:48:18 +08:00
lbl8603 5bdc514606 增加转发日志 2024-04-21 18:30:33 +08:00
lbl8603 137efe20b8 增加密钥hash,方便客户端判断加密是否一致 2024-04-20 21:27:35 +08:00
lbl8603 0cbc3e0f63 双重探测NAT类型,用于检测某些对称网络 2024-04-20 16:15:45 +08:00
lbl8603 7fbcf0a832 Merge remote-tracking branch 'origin/2024-04-19' into 2024-04-19 2024-04-20 14:49:57 +08:00
lbl8603 7283863fe8 增加路由回调 2024-04-20 14:48:58 +08:00
lbl8603 198f82fb2c 修改ip转u32方式 2024-04-19 20:05:19 +08:00
lubeilin c219af4f4b 增加额外路由 2024-04-19 18:44:22 +08:00
lubeilin 0352982c14 回调增加网络路由 2024-04-19 18:35:37 +08:00
lubeilin cc6cd6dc37 去除多余代码 2024-04-19 18:07:41 +08:00
lubeilin 9155471c26 去除多余代码 2024-04-19 16:28:49 +08:00
lubeilin d916fd7573 去除多余字段 2024-04-19 16:17:39 +08:00
lubeilin 5528557964 去除多余字段 2024-04-19 16:16:49 +08:00
lbl8603 8dfc3b8c43 修改安卓端逻辑 2024-04-19 10:49:47 +08:00
lubeilin 84824731a7 优化nat探测 2024-04-16 23:20:24 +08:00
lubeilin 7131937d06 fmt 2024-04-13 17:45:46 +08:00
lubeilin a657eae599 优化加密状态下的重连 2024-04-13 11:13:37 +08:00
lubeilin e9ec6e8903 增加丢包日志 2024-04-13 10:24:29 +08:00
68 changed files with 3622 additions and 543 deletions
+18
View File
@@ -51,9 +51,15 @@ jobs:
- TARGET: armv7-unknown-linux-musleabihf # raspberry pi 2-3-4, not tested
OS: ubuntu-latest
FEATURES: openssl-vendored
- TARGET: armv7-unknown-linux-musleabi # raspberry pi 2-3-4, not tested
OS: ubuntu-latest
FEATURES: openssl-vendored
- TARGET: arm-unknown-linux-musleabihf # raspberry pi 0-1, not tested
OS: ubuntu-latest
FEATURES: ring-cipher,openssl-vendored
- TARGET: arm-unknown-linux-musleabi # raspberry pi 0-1, not tested
OS: ubuntu-latest
FEATURES: ring-cipher,openssl-vendored
- TARGET: x86_64-apple-darwin # tested on a mac, is not properly signed so there are security warnings
OS: macos-latest
FEATURES: ring-cipher,openssl-vendored
@@ -111,9 +117,15 @@ jobs:
;;
armv7-unknown-linux-musleabihf)
MUSL_URI=armv7l-linux-musleabihf-cross
;;
armv7-unknown-linux-musleabi)
MUSL_URI=armv7m-linux-musleabi-cross
;;
arm-unknown-linux-musleabihf)
MUSL_URI=arm-linux-musleabihf-cross
;;
arm-unknown-linux-musleabi)
MUSL_URI=arm-linux-musleabi-cross
;;
mips-unknown-linux-musl)
MUSL_URI=mips-linux-musl-cross
@@ -145,8 +157,14 @@ jobs:
[target.armv7-unknown-linux-musleabihf]
linker = "armv7l-linux-musleabihf-gcc"
rustflags = ["-C", "target-feature=+crt-static","-C", "strip=symbols"]
[target.armv7-unknown-linux-musleabi]
linker = "armv7m-linux-musleabi-gcc"
rustflags = ["-C", "target-feature=+crt-static","-C", "strip=symbols"]
[target.arm-unknown-linux-musleabihf]
linker = "arm-linux-musleabihf-gcc"
rustflags = ["-C", "target-feature=+crt-static","-C", "strip=symbols"]
[target.arm-unknown-linux-musleabi]
linker = "arm-linux-musleabi-gcc"
rustflags = ["-C", "target-feature=+crt-static","-C", "strip=symbols"]
[target.mipsel-unknown-linux-musl]
linker = "mipsel-linux-musl-gcc"
+1 -2
View File
@@ -1,4 +1,3 @@
target/*
vnt/src/proto/*
vnt-cli/src/generated_serial_number.rs
Cargo.lock
vnt-cli/src/generated_serial_number.rs
Generated
+1853
View File
@@ -0,0 +1,1853 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "aead"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0"
dependencies = [
"crypto-common",
"generic-array",
]
[[package]]
name = "aes"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0"
dependencies = [
"cfg-if",
"cipher",
"cpufeatures",
]
[[package]]
name = "aes-gcm"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1"
dependencies = [
"aead",
"aes",
"cipher",
"ctr",
"ghash",
"subtle",
]
[[package]]
name = "aho-corasick"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
dependencies = [
"memchr",
]
[[package]]
name = "android-tzdata"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
[[package]]
name = "android_system_properties"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
dependencies = [
"libc",
]
[[package]]
name = "anyhow"
version = "1.0.82"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519"
[[package]]
name = "arc-swap"
version = "1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457"
[[package]]
name = "autocfg"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80"
[[package]]
name = "base64ct"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
[[package]]
name = "block-buffer"
version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
dependencies = [
"generic-array",
]
[[package]]
name = "block-padding"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93"
dependencies = [
"generic-array",
]
[[package]]
name = "bumpalo"
version = "3.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
[[package]]
name = "byteorder"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "bytes"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9"
[[package]]
name = "cbc"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6"
dependencies = [
"cipher",
]
[[package]]
name = "cc"
version = "1.0.94"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17f6e324229dc011159fcc089755d1e2e216a90d43a7dea6853ca740b84f35e7"
[[package]]
name = "cesu8"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chrono"
version = "0.4.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401"
dependencies = [
"android-tzdata",
"iana-time-zone",
"js-sys",
"num-traits",
"wasm-bindgen",
"windows-targets 0.52.5",
]
[[package]]
name = "cipher"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"
dependencies = [
"crypto-common",
"inout",
]
[[package]]
name = "combine"
version = "4.6.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd"
dependencies = [
"bytes",
"memchr",
]
[[package]]
name = "common"
version = "1.2.9"
[[package]]
name = "console"
version = "0.15.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb"
dependencies = [
"encode_unicode",
"lazy_static",
"libc",
"unicode-width",
"windows-sys 0.52.0",
]
[[package]]
name = "const-oid"
version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
[[package]]
name = "core-foundation-sys"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
[[package]]
name = "cpufeatures"
version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504"
dependencies = [
"libc",
]
[[package]]
name = "crossbeam-epoch"
version = "0.9.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
dependencies = [
"crossbeam-utils",
]
[[package]]
name = "crossbeam-queue"
version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35"
dependencies = [
"crossbeam-utils",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345"
[[package]]
name = "crypto-common"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
dependencies = [
"generic-array",
"rand_core",
"typenum",
]
[[package]]
name = "ctr"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835"
dependencies = [
"cipher",
]
[[package]]
name = "der"
version = "0.7.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0"
dependencies = [
"const-oid",
"pem-rfc7468",
"zeroize",
]
[[package]]
name = "derivative"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
dependencies = [
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]]
name = "destructure_traitobject"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c877555693c14d2f84191cfd3ad8582790fc52b5e2274b40b59cf5f5cea25c7"
[[package]]
name = "digest"
version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"block-buffer",
"const-oid",
"crypto-common",
]
[[package]]
name = "dns-parser"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4d33be9473d06f75f58220f71f7a9317aca647dc061dbd3c361b0bef505fbea"
dependencies = [
"byteorder",
"quick-error",
]
[[package]]
name = "ecb"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a8bfa975b1aec2145850fcaa1c6fe269a16578c44705a532ae3edc92b8881c7"
dependencies = [
"cipher",
]
[[package]]
name = "either"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2"
[[package]]
name = "embed-manifest"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41cd446c890d6bed1d8b53acef5f240069ebef91d6fae7c5f52efe61fe8b5eae"
[[package]]
name = "encode_unicode"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
[[package]]
name = "equivalent"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "errno"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245"
dependencies = [
"libc",
"windows-sys 0.52.0",
]
[[package]]
name = "fastrand"
version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984"
[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "generic-array"
version = "0.14.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
dependencies = [
"typenum",
"version_check",
]
[[package]]
name = "getopts"
version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5"
dependencies = [
"unicode-width",
]
[[package]]
name = "getrandom"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c"
dependencies = [
"cfg-if",
"js-sys",
"libc",
"wasi",
"wasm-bindgen",
]
[[package]]
name = "ghash"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1"
dependencies = [
"opaque-debug",
"polyval",
]
[[package]]
name = "hashbrown"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
[[package]]
name = "hashbrown"
version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
[[package]]
name = "home"
version = "0.5.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5"
dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "humantime"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
[[package]]
name = "iana-time-zone"
version = "0.1.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141"
dependencies = [
"android_system_properties",
"core-foundation-sys",
"iana-time-zone-haiku",
"js-sys",
"wasm-bindgen",
"windows-core",
]
[[package]]
name = "iana-time-zone-haiku"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
dependencies = [
"cc",
]
[[package]]
name = "indexmap"
version = "1.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
dependencies = [
"autocfg",
"hashbrown 0.12.3",
]
[[package]]
name = "indexmap"
version = "2.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26"
dependencies = [
"equivalent",
"hashbrown 0.14.3",
]
[[package]]
name = "inout"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5"
dependencies = [
"block-padding",
"generic-array",
]
[[package]]
name = "ioctl-sys"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8bd11f3a29434026f5ff98c730b668ba74b1033637b8817940b54d040696133c"
[[package]]
name = "itoa"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
[[package]]
name = "jni"
version = "0.21.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97"
dependencies = [
"cesu8",
"cfg-if",
"combine",
"jni-sys",
"log",
"thiserror",
"walkdir",
"windows-sys 0.45.0",
]
[[package]]
name = "jni-sys"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
[[package]]
name = "js-sys"
version = "0.3.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d"
dependencies = [
"wasm-bindgen",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
dependencies = [
"spin 0.5.2",
]
[[package]]
name = "libc"
version = "0.2.153"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
[[package]]
name = "libloading"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19"
dependencies = [
"cfg-if",
"windows-targets 0.52.5",
]
[[package]]
name = "libm"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058"
[[package]]
name = "libsm"
version = "0.5.1"
source = "git+https://github.com/lbl8603/libsm#f9e1b8cf20d0829efb4934a940d0ba4f3ee0ac14"
dependencies = [
"byteorder",
"getrandom",
"lazy_static",
"num-bigint",
"num-integer",
"num-traits",
"rand",
"yasna",
]
[[package]]
name = "linux-raw-sys"
version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c"
[[package]]
name = "lock_api"
version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45"
dependencies = [
"autocfg",
"scopeguard",
]
[[package]]
name = "log"
version = "0.4.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
dependencies = [
"serde",
]
[[package]]
name = "log-mdc"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a94d21414c1f4a51209ad204c1776a3d0765002c76c6abcb602a6f09f1e881c7"
[[package]]
name = "log4rs"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0816135ae15bd0391cf284eab37e6e3ee0a6ee63d2ceeb659862bd8d0a984ca6"
dependencies = [
"anyhow",
"arc-swap",
"chrono",
"derivative",
"fnv",
"humantime",
"libc",
"log",
"log-mdc",
"once_cell",
"parking_lot",
"rand",
"serde",
"serde-value",
"serde_json",
"serde_yaml",
"thiserror",
"thread-id",
"typemap-ors",
"winapi",
]
[[package]]
name = "memchr"
version = "2.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d"
[[package]]
name = "mio"
version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c"
dependencies = [
"libc",
"log",
"wasi",
"windows-sys 0.48.0",
]
[[package]]
name = "num-bigint"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0"
dependencies = [
"autocfg",
"num-integer",
"num-traits",
]
[[package]]
name = "num-bigint-dig"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151"
dependencies = [
"byteorder",
"lazy_static",
"libm",
"num-integer",
"num-iter",
"num-traits",
"rand",
"smallvec",
"zeroize",
]
[[package]]
name = "num-integer"
version = "0.1.46"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f"
dependencies = [
"num-traits",
]
[[package]]
name = "num-iter"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d869c01cc0c455284163fd0092f1f93835385ccab5a98a0dcc497b2f8bf055a9"
dependencies = [
"autocfg",
"num-integer",
"num-traits",
]
[[package]]
name = "num-traits"
version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a"
dependencies = [
"autocfg",
"libm",
]
[[package]]
name = "once_cell"
version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
[[package]]
name = "opaque-debug"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"
[[package]]
name = "openssl-src"
version = "300.1.3+3.1.2"
source = "git+https://github.com/lbl8603/openssl-src-rs#871c5d6cfe8a7cb1c5725638d7563c0d96ca4c04"
dependencies = [
"cc",
]
[[package]]
name = "openssl-sys"
version = "0.9.93"
source = "git+https://github.com/lbl8603/rust-openssl#e8b3d2c02d2d07a0e4a82ff4e4bef210f4bc71c8"
dependencies = [
"cc",
"libc",
"openssl-src",
"pkg-config",
"vcpkg",
]
[[package]]
name = "ordered-float"
version = "2.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68f19d67e5a2795c94e73e0bb1cc1a7edeb2e28efd39e2e1c9b7a40c1108b11c"
dependencies = [
"num-traits",
]
[[package]]
name = "os_info"
version = "3.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae99c7fa6dd38c7cafe1ec085e804f8f555a2f8659b0dbe03f1f9963a9b51092"
dependencies = [
"log",
"serde",
"windows-sys 0.52.0",
]
[[package]]
name = "packet"
version = "0.1.0"
dependencies = [
"byteorder",
]
[[package]]
name = "parking_lot"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
dependencies = [
"lock_api",
"parking_lot_core",
]
[[package]]
name = "parking_lot_core"
version = "0.9.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e"
dependencies = [
"cfg-if",
"libc",
"redox_syscall",
"smallvec",
"windows-targets 0.48.5",
]
[[package]]
name = "pem-rfc7468"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412"
dependencies = [
"base64ct",
]
[[package]]
name = "pkcs1"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f"
dependencies = [
"der",
"pkcs8",
"spki",
]
[[package]]
name = "pkcs8"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7"
dependencies = [
"der",
"spki",
]
[[package]]
name = "pkg-config"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
[[package]]
name = "polyval"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25"
dependencies = [
"cfg-if",
"cpufeatures",
"opaque-debug",
"universal-hash",
]
[[package]]
name = "ppv-lite86"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
name = "proc-macro2"
version = "1.0.81"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba"
dependencies = [
"unicode-ident",
]
[[package]]
name = "protobuf"
version = "3.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "58678a64de2fced2bdec6bca052a6716a0efe692d6e3f53d1bda6a1def64cfc0"
dependencies = [
"once_cell",
"protobuf-support",
"thiserror",
]
[[package]]
name = "protobuf-codegen"
version = "3.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32777b0b3f6538d9d2e012b3fad85c7e4b9244b5958d04a6415f4333782b7a77"
dependencies = [
"anyhow",
"once_cell",
"protobuf",
"protobuf-parse",
"regex",
"tempfile",
"thiserror",
]
[[package]]
name = "protobuf-parse"
version = "3.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96cb37955261126624a25b5e6bda40ae34cf3989d52a783087ca6091b29b5642"
dependencies = [
"anyhow",
"indexmap 1.9.3",
"log",
"protobuf",
"protobuf-support",
"tempfile",
"thiserror",
"which",
]
[[package]]
name = "protobuf-support"
version = "3.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1ed294a835b0f30810e13616b1cd34943c6d1e84a8f3b0dcfe466d256c3e7e7"
dependencies = [
"thiserror",
]
[[package]]
name = "protoc-bin-vendored"
version = "3.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "005ca8623e5633e298ad1f917d8be0a44bcf406bf3cde3b80e63003e49a3f27d"
dependencies = [
"protoc-bin-vendored-linux-aarch_64",
"protoc-bin-vendored-linux-ppcle_64",
"protoc-bin-vendored-linux-x86_32",
"protoc-bin-vendored-linux-x86_64",
"protoc-bin-vendored-macos-x86_64",
"protoc-bin-vendored-win32",
]
[[package]]
name = "protoc-bin-vendored-linux-aarch_64"
version = "3.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fb9fc9cce84c8694b6ea01cc6296617b288b703719b725b8c9c65f7c5874435"
[[package]]
name = "protoc-bin-vendored-linux-ppcle_64"
version = "3.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02d2a07dcf7173a04d49974930ccbfb7fd4d74df30ecfc8762cf2f895a094516"
[[package]]
name = "protoc-bin-vendored-linux-x86_32"
version = "3.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d54fef0b04fcacba64d1d80eed74a20356d96847da8497a59b0a0a436c9165b0"
[[package]]
name = "protoc-bin-vendored-linux-x86_64"
version = "3.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8782f2ce7d43a9a5c74ea4936f001e9e8442205c244f7a3d4286bd4c37bc924"
[[package]]
name = "protoc-bin-vendored-macos-x86_64"
version = "3.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5de656c7ee83f08e0ae5b81792ccfdc1d04e7876b1d9a38e6876a9e09e02537"
[[package]]
name = "protoc-bin-vendored-win32"
version = "3.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9653c3ed92974e34c5a6e0a510864dab979760481714c172e0a34e437cb98804"
[[package]]
name = "quick-error"
version = "1.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
[[package]]
name = "quote"
version = "1.0.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
dependencies = [
"proc-macro2",
]
[[package]]
name = "r-ex"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42776a943a4f890410259860d4c308d32792ecbeaca4932a2b94b04f6d27bb9a"
[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom",
]
[[package]]
name = "redox_syscall"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
dependencies = [
"bitflags 1.3.2",
]
[[package]]
name = "regex"
version = "1.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56"
[[package]]
name = "ring"
version = "0.17.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d"
dependencies = [
"cc",
"cfg-if",
"getrandom",
"libc",
"spin 0.9.8",
"untrusted",
"windows-sys 0.52.0",
]
[[package]]
name = "rsa"
version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d0e5124fcb30e76a7e79bfee683a2746db83784b86289f6251b54b7950a0dfc"
dependencies = [
"const-oid",
"digest",
"num-bigint-dig",
"num-integer",
"num-traits",
"pkcs1",
"pkcs8",
"rand_core",
"signature",
"spki",
"subtle",
"zeroize",
]
[[package]]
name = "rustix"
version = "0.38.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89"
dependencies = [
"bitflags 2.5.0",
"errno",
"libc",
"linux-raw-sys",
"windows-sys 0.52.0",
]
[[package]]
name = "ryu"
version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1"
[[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 = "scopeguard"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "serde"
version = "1.0.198"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9846a40c979031340571da2545a4e5b7c4163bdae79b301d5f86d03979451fcc"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde-value"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c"
dependencies = [
"ordered-float",
"serde",
]
[[package]]
name = "serde_derive"
version = "1.0.198"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e88edab869b01783ba905e7d0153f9fc1a6505a96e4ad3018011eedb838566d9"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.60",
]
[[package]]
name = "serde_json"
version = "1.0.116"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813"
dependencies = [
"itoa",
"ryu",
"serde",
]
[[package]]
name = "serde_yaml"
version = "0.9.34+deprecated"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47"
dependencies = [
"indexmap 2.2.6",
"itoa",
"ryu",
"serde",
"unsafe-libyaml",
]
[[package]]
name = "sha2"
version = "0.10.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
dependencies = [
"cfg-if",
"cpufeatures",
"digest",
]
[[package]]
name = "signature"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
dependencies = [
"digest",
"rand_core",
]
[[package]]
name = "smallvec"
version = "1.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
[[package]]
name = "socket2"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871"
dependencies = [
"libc",
"windows-sys 0.52.0",
]
[[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.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
[[package]]
name = "spki"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d"
dependencies = [
"base64ct",
"der",
"sha2",
]
[[package]]
name = "stun-bytes"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3bebd666814c8af1e06e4d489f9c3d03a4aef20bae651550c52e6e95e09f3f12"
dependencies = [
"r-ex",
]
[[package]]
name = "stun-format"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c6ad3c54fde6dfd6fe5048a71515b392d22c29730533663b5300e1b511d78df5"
dependencies = [
"r-ex",
"stun-bytes",
]
[[package]]
name = "subtle"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
[[package]]
name = "sudo"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88bd84d4c082e18e37fef52c0088e4407dabcef19d23a607fb4b5ee03b7d5b83"
dependencies = [
"libc",
"log",
]
[[package]]
name = "syn"
version = "1.0.109"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "syn"
version = "2.0.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "tempfile"
version = "3.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1"
dependencies = [
"cfg-if",
"fastrand",
"rustix",
"windows-sys 0.52.0",
]
[[package]]
name = "thiserror"
version = "1.0.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.60",
]
[[package]]
name = "thread-id"
version = "4.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0ec81c46e9eb50deaa257be2f148adf052d1fb7701cfd55ccfab2525280b70b"
dependencies = [
"libc",
"winapi",
]
[[package]]
name = "tun"
version = "0.1.0"
dependencies = [
"ioctl-sys",
"libc",
"libloading",
"log",
"rand",
"widestring",
"winapi",
]
[[package]]
name = "typemap-ors"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a68c24b707f02dd18f1e4ccceb9d49f2058c2fb86384ef9972592904d7a28867"
dependencies = [
"unsafe-any-ors",
]
[[package]]
name = "typenum"
version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "unicode-width"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
[[package]]
name = "universal-hash"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea"
dependencies = [
"crypto-common",
"subtle",
]
[[package]]
name = "unsafe-any-ors"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0a303d30665362d9680d7d91d78b23f5f899504d4f08b3c4cf08d055d87c0ad"
dependencies = [
"destructure_traitobject",
]
[[package]]
name = "unsafe-libyaml"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861"
[[package]]
name = "untrusted"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
[[package]]
name = "uuid"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0"
dependencies = [
"getrandom",
]
[[package]]
name = "vcpkg"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]]
name = "version_check"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "vnt"
version = "1.2.9"
dependencies = [
"aes",
"aes-gcm",
"anyhow",
"bytes",
"cbc",
"crossbeam-epoch",
"crossbeam-queue",
"crossbeam-utils",
"dns-parser",
"ecb",
"libc",
"libloading",
"libsm",
"log",
"mio",
"openssl-sys",
"packet",
"parking_lot",
"protobuf",
"protobuf-codegen",
"protoc-bin-vendored",
"rand",
"ring",
"rsa",
"sha2",
"socket2",
"spki",
"stun-format",
"thiserror",
"tun",
]
[[package]]
name = "vnt-cli"
version = "1.2.9"
dependencies = [
"chrono",
"common",
"console",
"embed-manifest",
"getopts",
"log",
"log4rs",
"os_info",
"rand",
"serde",
"serde_yaml",
"sudo",
"uuid",
"vnt",
"winapi",
]
[[package]]
name = "vnt-jni"
version = "1.2.9"
dependencies = [
"common",
"jni",
"log",
"parking_lot",
"spki",
"vnt",
]
[[package]]
name = "walkdir"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
dependencies = [
"same-file",
"winapi-util",
]
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasm-bindgen"
version = "0.2.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8"
dependencies = [
"cfg-if",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da"
dependencies = [
"bumpalo",
"log",
"once_cell",
"proc-macro2",
"quote",
"syn 2.0.60",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.60",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96"
[[package]]
name = "which"
version = "4.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7"
dependencies = [
"either",
"home",
"once_cell",
"rustix",
]
[[package]]
name = "widestring"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596"
dependencies = [
"winapi",
]
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-core"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
dependencies = [
"windows-targets 0.52.5",
]
[[package]]
name = "windows-sys"
version = "0.45.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
dependencies = [
"windows-targets 0.42.2",
]
[[package]]
name = "windows-sys"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
dependencies = [
"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.5",
]
[[package]]
name = "windows-targets"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
dependencies = [
"windows_aarch64_gnullvm 0.42.2",
"windows_aarch64_msvc 0.42.2",
"windows_i686_gnu 0.42.2",
"windows_i686_msvc 0.42.2",
"windows_x86_64_gnu 0.42.2",
"windows_x86_64_gnullvm 0.42.2",
"windows_x86_64_msvc 0.42.2",
]
[[package]]
name = "windows-targets"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
dependencies = [
"windows_aarch64_gnullvm 0.48.5",
"windows_aarch64_msvc 0.48.5",
"windows_i686_gnu 0.48.5",
"windows_i686_msvc 0.48.5",
"windows_x86_64_gnu 0.48.5",
"windows_x86_64_gnullvm 0.48.5",
"windows_x86_64_msvc 0.48.5",
]
[[package]]
name = "windows-targets"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb"
dependencies = [
"windows_aarch64_gnullvm 0.52.5",
"windows_aarch64_msvc 0.52.5",
"windows_i686_gnu 0.52.5",
"windows_i686_gnullvm",
"windows_i686_msvc 0.52.5",
"windows_x86_64_gnu 0.52.5",
"windows_x86_64_gnullvm 0.52.5",
"windows_x86_64_msvc 0.52.5",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263"
[[package]]
name = "windows_aarch64_msvc"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6"
[[package]]
name = "windows_i686_gnu"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
[[package]]
name = "windows_i686_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]]
name = "windows_i686_gnu"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9"
[[package]]
name = "windows_i686_msvc"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
[[package]]
name = "windows_i686_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]]
name = "windows_i686_msvc"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf"
[[package]]
name = "windows_x86_64_gnu"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596"
[[package]]
name = "windows_x86_64_msvc"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0"
[[package]]
name = "yasna"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd"
dependencies = [
"num-bigint",
]
[[package]]
name = "zeroize"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d"
+2 -2
View File
@@ -68,10 +68,10 @@ pub fn out_ips_parse(ips: &Vec<String>) -> Result<Vec<(u32, u32)>, String> {
pub fn to_ip(mask: &str) -> Result<u32, String> {
if let Ok(m) = mask.parse::<u32>() {
if m >= 32 {
if m > 32 {
return Err("not netmask".to_string());
}
let mut mask = 0 as u32;
let mut mask = 0u32;
for i in 0..m {
mask = mask | (1 << (31 - i));
}
+2
View File
@@ -121,6 +121,8 @@ first_latency: false #是否优先低延迟通道,默认为false,表示优
device_name: vnt-tun #网卡名称
packet_loss: 0 #指定丢包率 取值0~1之间的数 用于模拟弱网
packet_delay: 0 #指定延迟 单位毫秒 用于模拟弱网
dns:
- 8.8.8.8:53
```
或者需要哪个配置就加哪个,当然token是必须的
+2
View File
@@ -36,5 +36,7 @@ pub struct DeviceItem {
pub rt: String,
pub status: String,
pub client_secret: bool,
pub client_secret_hash: Vec<u8>,
pub current_client_secret: bool,
pub current_client_secret_hash: Vec<u8>,
}
+3
View File
@@ -85,6 +85,7 @@ pub fn command_list(vnt: &Vnt) -> Vec<DeviceItem> {
let device_list = vnt.device_list();
let mut list = Vec::new();
let current_client_secret = vnt.client_encrypt();
let client_encrypt_hash = vnt.client_encrypt_hash().unwrap_or(&[]);
for peer in device_list {
let name = peer.name;
let virtual_ip = peer.virtual_ip.to_string();
@@ -153,7 +154,9 @@ pub fn command_list(vnt: &Vnt) -> Vec<DeviceItem> {
rt,
status,
client_secret,
client_secret_hash: peer.client_secret_hash,
current_client_secret,
current_client_secret_hash: client_encrypt_hash.to_vec(),
};
list.push(item);
}
+5 -20
View File
@@ -1,5 +1,5 @@
use std::io;
use std::net::{Ipv4Addr, ToSocketAddrs};
use std::net::Ipv4Addr;
use std::str::FromStr;
use serde::{Deserialize, Serialize};
@@ -19,6 +19,7 @@ pub struct FileConfig {
pub name: String,
pub server_address: String,
pub stun_server: Vec<String>,
pub dns: Vec<String>,
pub in_ips: Vec<String>,
pub out_ips: Vec<String>,
pub password: Option<String>,
@@ -55,6 +56,7 @@ impl Default for FileConfig {
"stun2.l.google.com:19302".to_string(),
"stun.qq.com:3478".to_string(),
],
dns: vec![],
in_ips: vec![],
out_ips: vec![],
password: None,
@@ -91,24 +93,7 @@ pub fn read_config(file_path: &str) -> io::Result<(Config, bool)> {
if file_conf.token.is_empty() {
return Err(io::Error::new(io::ErrorKind::Other, "token is_empty"));
}
let server_address = match file_conf.server_address.to_socket_addrs() {
Ok(mut addr) => {
if let Some(addr) = addr.next() {
addr
} else {
return Err(io::Error::new(
io::ErrorKind::Other,
format!("server_address {:?} error", &file_conf.server_address),
));
}
}
Err(e) => {
return Err(io::Error::new(
io::ErrorKind::Other,
format!("server_address {:?} error:{}", &file_conf.server_address, e),
));
}
};
let in_ips = match common::args_parse::ips_parse(&file_conf.in_ips) {
Ok(in_ips) => in_ips,
Err(e) => {
@@ -150,8 +135,8 @@ pub fn read_config(file_path: &str) -> io::Result<(Config, bool)> {
file_conf.token,
file_conf.device_id,
file_conf.name,
server_address,
file_conf.server_address,
file_conf.dns,
file_conf.stun_server,
in_ips,
out_ips,
+7 -2
View File
@@ -21,6 +21,7 @@ pub fn console_info(status: Info) {
println!("Up: {}", style(convert(status.up)).green());
println!("Down: {}", style(convert(status.down)).green());
}
fn convert(num: u64) -> String {
let gigabytes = num / (1024 * 1024 * 1024);
let remaining_bytes = num % (1024 * 1024 * 1024);
@@ -90,13 +91,17 @@ pub fn console_device_list(mut list: Vec<DeviceItem>) {
]);
for item in list {
if &item.status == "Online" {
if item.client_secret != item.current_client_secret {
if item.client_secret != item.current_client_secret
|| (!item.current_client_secret_hash.is_empty()
&& !item.client_secret_hash.is_empty()
&& item.current_client_secret_hash != item.client_secret_hash)
{
//加密状态不一致,无法通信的
out_list.push(vec![
(item.name, Style::new().red()),
(item.virtual_ip, Style::new().red()),
(item.status, Style::new().red()),
("".to_string(), Style::new().red()),
("Mismatch".to_string(), Style::new().red()),
("".to_string(), Style::new().red()),
]);
} else {
+7 -18
View File
@@ -1,4 +1,4 @@
use std::net::{Ipv4Addr, ToSocketAddrs};
use std::net::Ipv4Addr;
use std::path::PathBuf;
use std::str::FromStr;
use std::{io, thread};
@@ -72,6 +72,7 @@ fn main() {
opts.optopt("", "use-channel", "使用通道 relay/p2p", "<use-channel>");
opts.optopt("", "packet-loss", "丢包率", "<packet-loss>");
opts.optopt("", "packet-delay", "延迟", "<packet-delay>");
opts.optmulti("", "dns", "dns", "<dns>");
opts.optopt("f", "", "配置文件", "<conf>");
//"后台运行时,查看其他设备列表"
opts.optflag("", "list", "后台运行时,查看其他设备列表");
@@ -150,27 +151,14 @@ fn main() {
let server_address_str = matches
.opt_get_default("s", "nat1.wherewego.top:29872".to_string())
.unwrap();
let server_address = match server_address_str.to_socket_addrs() {
Ok(mut addr) => {
if let Some(addr) = addr.next() {
addr
} else {
println!("parameter '-s {}' error .", server_address_str);
return;
}
}
Err(e) => {
println!("parameter '-s {}' error {}.", server_address_str, e);
return;
}
};
let mut stun_server = matches.opt_strs("e");
if stun_server.is_empty() {
stun_server.push("stun1.l.google.com:19302".to_string());
stun_server.push("stun2.l.google.com:19302".to_string());
stun_server.push("stun.qq.com:3478".to_string());
}
let dns = matches.opt_strs("dns");
let in_ip = matches.opt_strs("i");
let in_ip = match ips_parse(&in_ip) {
Ok(in_ip) => in_ip,
@@ -305,8 +293,8 @@ fn main() {
token,
device_id,
name,
server_address,
server_address_str,
dns,
stun_server,
in_ip,
out_ip,
@@ -423,7 +411,7 @@ fn print_usage(program: &str, _opts: Options) {
);
println!(" -n <name> 给设备一个名字,便于区分不同设备,默认使用系统版本");
println!(" -d <id> 设备唯一标识符,不使用--ip参数时,服务端凭此参数分配虚拟ip,注意不能重复");
println!(" -s <server> 注册和中继服务器地址");
println!(" -s <server> 注册和中继服务器地址,以'TXT:'开头表示解析TXT记录");
println!(" -e <stun-server> stun服务器,用于探测NAT类型,可多次指定,如-e addr1 -e addr2");
println!(" -a 使用tap模式,默认使用tun模式");
println!(" -i <in-ip> 配置点对网(IP代理)时使用,-i 192.168.0.0/24,10.26.0.3表示允许接收网段192.168.0.0/24的数据");
@@ -486,6 +474,7 @@ fn print_usage(program: &str, _opts: Options) {
println!(
" --packet-delay <0> 模拟延迟,整数,单位毫秒(ms),程序会按设定的值延迟发包,可用于模拟弱网"
);
println!(" --dns <host:port> DNS服务器地址,可使用多个dns,不指定时使用系统解析");
println!();
println!(
@@ -12,8 +12,10 @@ public interface CallBack {
* 连接成功的回调
*/
void success();
/**
* 创建虚拟网卡成功的回调方法
* 仅在 windows/linux/macos上使用
*
* @param info 网卡信息
*/
@@ -42,6 +44,24 @@ public interface CallBack {
*/
boolean register(RegisterInfo info);
/**
* 创建网卡回调
* 仅在android上使用
*
* @param info 创建配置
* @return 网卡fd
*/
int generateTun(DeviceConfig info);
/**
* 对端用户列表
*
* @param infoArray
*/
void peerClientList(PeerClientInfo[] infoArray);
/**
* 异常回调
*
+12 -12
View File
@@ -50,6 +50,10 @@ public class Config {
* 服务端地址
*/
private String server;
/**
* dns地址
*/
private String[] dns;
/**
* stun服务地址
*/
@@ -86,10 +90,6 @@ public class Config {
* 虚拟网卡名称 仅在linux、windows、macos上支持
*/
private String deviceName;
/**
* 虚拟网卡fd 仅在android上支持
*/
private int deviceFd;
/**
* enum: relay/p2p/all
*/
@@ -194,6 +194,14 @@ public class Config {
this.server = server;
}
public String[] getDns() {
return dns;
}
public void setDns(String[] dns) {
this.dns = dns;
}
public String[] getStunServer() {
return stunServer;
}
@@ -266,14 +274,6 @@ public class Config {
this.deviceName = deviceName;
}
public int getDeviceFd() {
return deviceFd;
}
public void setDeviceFd(int deviceFd) {
this.deviceFd = deviceFd;
}
public String getUseChannel() {
return useChannel;
}
@@ -6,6 +6,12 @@ package top.wherewego.vnt.jni;
* @author https://github.com/lbl8603/vnt
*/
public class IpUtils {
/**
* 将整数的ip地址转成字符串,例如 0 转成 "0.0.0.0"
*
* @param ipAddress
* @return
*/
public static String intToIpAddress(int ipAddress) {
return ((ipAddress & 0xFF000000) >>> 24) + "." +
@@ -13,6 +19,13 @@ public class IpUtils {
((ipAddress & 0x0000FF00) >>> 8) + "." +
(ipAddress & 0x000000FF);
}
/**
* 返回掩码的长度
*
* @param subnetMask
* @return
*/
public static int subnetMaskToPrefixLength(int subnetMask) {
int prefixLength = 0;
int bit = 1 << 31;
@@ -5,13 +5,13 @@ package top.wherewego.vnt.jni;
*
* @author https://github.com/lbl8603/vnt
*/
public class PeerDeviceInfo {
public class PeerRouteInfo {
private final int virtualIp;
private final String name;
private final String status;
private final Route route;
public PeerDeviceInfo(int virtualIp, String name, String status, Route route) {
public PeerRouteInfo(int virtualIp, String name, String status, Route route) {
this.virtualIp = virtualIp;
this.name = name;
this.status = status;
+13 -2
View File
@@ -6,16 +6,26 @@ package top.wherewego.vnt.jni;
* @author https://github.com/lbl8603/vnt
*/
public class Route {
/**
* 是否使用tcp
*/
private final boolean tcp;
private final String address;
private final byte metric;
private final int rt;
public Route(String address, byte metric, int rt) {
public Route(boolean tcp, String address, byte metric, int rt) {
this.tcp = tcp;
this.address = address;
this.metric = metric;
this.rt = rt;
}
public boolean isTcp() {
return tcp;
}
public String getAddress() {
return address;
}
@@ -31,7 +41,8 @@ public class Route {
@Override
public String toString() {
return "Route{" +
"address='" + address + '\'' +
"tcp=" + tcp +
", address='" + address + '\'' +
", metric=" + metric +
", rt=" + rt +
'}';
+5 -2
View File
@@ -13,6 +13,9 @@ public class Vnt implements Closeable {
public Vnt(Config config, CallBack callBack) throws Exception{
this.raw = new0(config, callBack);
if (this.raw == 0) {
throw new RuntimeException();
}
}
public void stop() {
@@ -23,7 +26,7 @@ public class Vnt implements Closeable {
wait0(raw);
}
public PeerDeviceInfo[] list() {
public PeerRouteInfo[] list() {
return list0(raw);
}
@@ -35,7 +38,7 @@ public class Vnt implements Closeable {
private native void drop0(long raw);
private native PeerDeviceInfo[] list0(long raw);
private native PeerRouteInfo[] list0(long raw);
@Override
public void close() throws IOException {
@@ -0,0 +1,72 @@
package top.wherewego.vnt.jni.param;
import top.wherewego.vnt.jni.IpUtils;
import java.util.Arrays;
/**
* 创建网卡所需信息,仅在android上使用
*
* @author https://github.com/lbl8603/vnt
*/
public class DeviceConfig {
/**
* 虚拟IP
*/
public final int virtualIp;
/**
* 掩码
*/
public final int virtualNetmask;
/**
* 网关
*/
public final int virtualGateway;
/**
* 虚拟网段
*/
public final int virtualNetwork;
/**
* 额外路由,来自点对网的路由配置
*/
public final String[] externalRoute;
public DeviceConfig(int virtualIp, int virtualNetmask, int virtualGateway, int virtualNetwork, String[] externalRoute) {
this.virtualIp = virtualIp;
this.virtualNetmask = virtualNetmask;
this.virtualGateway = virtualGateway;
this.virtualNetwork = virtualNetwork;
this.externalRoute = externalRoute;
}
public int getVirtualIp() {
return virtualIp;
}
public int getVirtualNetmask() {
return virtualNetmask;
}
public int getVirtualGateway() {
return virtualGateway;
}
public int getVirtualNetwork() {
return virtualNetwork;
}
public String[] getExternalRoute() {
return externalRoute;
}
@Override
public String toString() {
return "DeviceConfig{" +
"virtualIp=" + IpUtils.intToIpAddress(virtualIp) +
", virtualNetmask=" + IpUtils.intToIpAddress(virtualNetmask) +
", virtualGateway=" + IpUtils.intToIpAddress(virtualGateway) +
", virtualNetwork=" + IpUtils.intToIpAddress(virtualNetwork) +
", externalRoute=" + Arrays.toString(externalRoute) +
'}';
}
}
@@ -1,7 +1,7 @@
package top.wherewego.vnt.jni.param;
/**
* 网卡信息
* 网卡信息 仅在 windows/linux/macos上使用
*
* @author https://github.com/lbl8603/vnt
*/
@@ -16,15 +16,25 @@ public class ErrorInfo {
public final String msg;
public ErrorInfo(int code, String msg) {
this.code = switch (code) {
case 1 -> ErrorCodeEnum.TokenError;
case 2 -> ErrorCodeEnum.Disconnect;
case 3 -> ErrorCodeEnum.AddressExhausted;
case 4 -> ErrorCodeEnum.IpAlreadyExists;
case 5 -> ErrorCodeEnum.InvalidIp;
case 6 -> ErrorCodeEnum.Unknown;
default -> null;
};
switch (code) {
case 1:
this.code = ErrorCodeEnum.TokenError;
break;
case 2:
this.code = ErrorCodeEnum.Disconnect;
break;
case 3:
this.code = ErrorCodeEnum.AddressExhausted;
break;
case 4:
this.code = ErrorCodeEnum.IpAlreadyExists;
break;
case 5:
this.code = ErrorCodeEnum.InvalidIp;
break;
default:
this.code = ErrorCodeEnum.Unknown;
}
this.msg = msg;
}
@@ -0,0 +1,60 @@
package top.wherewego.vnt.jni.param;
import top.wherewego.vnt.jni.IpUtils;
/**
* 创建网卡所需信息,仅在android上使用
*
* @author https://github.com/lbl8603/vnt
*/
public class PeerClientInfo {
/**
* 虚拟IP
*/
public final int virtualIp;
/**
* 名称
*/
public final String name;
/**
* 是否在线
*/
public final boolean online;
/**
* 是否开启客户端加密,不同加密状态的不能通信
*/
public final boolean clientSecret;
public PeerClientInfo(int virtualIp, String name, boolean online, boolean clientSecret) {
this.virtualIp = virtualIp;
this.name = name;
this.online = online;
this.clientSecret = clientSecret;
}
public int getVirtualIp() {
return virtualIp;
}
public String getName() {
return name;
}
public boolean isOnline() {
return online;
}
public boolean isClientSecret() {
return clientSecret;
}
@Override
public String toString() {
return "PeerDeviceInfo{" +
"virtualIp=" + IpUtils.intToIpAddress(virtualIp) +
", name='" + name + '\'' +
", online=" + online +
", clientSecret=" + clientSecret +
'}';
}
}
@@ -1,5 +1,7 @@
package top.wherewego.vnt.jni.param;
import top.wherewego.vnt.jni.IpUtils;
/**
* 注册回调信息
*
@@ -9,40 +11,40 @@ public class RegisterInfo {
/**
* 虚拟IP
*/
public final String virtualIp;
public final int virtualIp;
/**
* 掩码
*/
public final String virtualNetmask;
public final int virtualNetmask;
/**
* 网关
*/
public final String virtualGateway;
public final int virtualGateway;
public RegisterInfo(String virtualIp, String virtualNetmask, String virtualGateway) {
public RegisterInfo(int virtualIp, int virtualNetmask, int virtualGateway) {
this.virtualIp = virtualIp;
this.virtualNetmask = virtualNetmask;
this.virtualGateway = virtualGateway;
}
public String getVirtualIp() {
public int getVirtualIp() {
return virtualIp;
}
public String getVirtualNetmask() {
public int getVirtualNetmask() {
return virtualNetmask;
}
public String getVirtualGateway() {
public int getVirtualGateway() {
return virtualGateway;
}
@Override
public String toString() {
return "RegisterInfo{" +
"virtualIp='" + virtualIp + '\'' +
", virtualNetmask='" + virtualNetmask + '\'' +
", virtualGateway='" + virtualGateway + '\'' +
"virtualIp='" + IpUtils.intToIpAddress(virtualIp) + '\'' +
", virtualNetmask='" + IpUtils.intToIpAddress(virtualNetmask) + '\'' +
", virtualGateway='" + IpUtils.intToIpAddress(virtualGateway) + '\'' +
'}';
}
}
+148 -21
View File
@@ -1,40 +1,87 @@
use std::sync::Arc;
use jni::objects::{GlobalRef, JString, JValue};
use jni::objects::{GlobalRef, JClass, JObject, JString, JValue};
use jni::{JNIEnv, JavaVM};
use spki::der::pem::LineEnding;
use spki::EncodePublicKey;
use vnt::handle::callback::ConnectInfo;
use vnt::{DeviceInfo, ErrorInfo, HandshakeInfo, RegisterInfo, VntCallback};
#[cfg(target_os = "android")]
use vnt::handle::callback::DeviceConfig;
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
use vnt::DeviceInfo;
use vnt::{ErrorInfo, HandshakeInfo, PeerClientInfo, RegisterInfo, VntCallback};
#[derive(Clone)]
pub struct CallBack {
jvm: Arc<JavaVM>,
this: GlobalRef,
connect_info_class: GlobalRef,
handshake_info_class: GlobalRef,
error_info_class: GlobalRef,
register_info_class: GlobalRef,
#[cfg(target_os = "android")]
device_config_class: GlobalRef,
peer_client_info_class: GlobalRef,
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
device_info_class: GlobalRef,
}
unsafe impl Send for CallBack {}
fn find_class_global_ref(env: &mut JNIEnv, class: &str) -> jni::errors::Result<GlobalRef> {
let class = env.find_class(class)?;
env.new_global_ref(class)
}
impl CallBack {
pub fn new(jvm: JavaVM, this: GlobalRef) -> Self {
Self {
pub fn new(jvm: JavaVM, this: GlobalRef) -> jni::errors::Result<Self> {
let mut env = jvm.attach_current_thread_as_daemon()?;
let connect_info_class =
find_class_global_ref(&mut env, "top/wherewego/vnt/jni/param/ConnectInfo")?;
let handshake_info_class =
find_class_global_ref(&mut env, "top/wherewego/vnt/jni/param/HandshakeInfo")?;
let error_info_class =
find_class_global_ref(&mut env, "top/wherewego/vnt/jni/param/ErrorInfo")?;
let register_info_class =
find_class_global_ref(&mut env, "top/wherewego/vnt/jni/param/RegisterInfo")?;
#[cfg(target_os = "android")]
let device_config_class = crate::callback::find_class_global_ref(
&mut env,
"top/wherewego/vnt/jni/param/DeviceConfig",
)?;
let peer_client_info_class =
find_class_global_ref(&mut env, "top/wherewego/vnt/jni/param/PeerClientInfo")?;
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
let device_info_class =
find_class_global_ref(&mut env, "top/wherewego/vnt/jni/param/DeviceInfo")?;
Ok(Self {
jvm: Arc::new(jvm),
this,
}
connect_info_class,
handshake_info_class,
error_info_class,
register_info_class,
#[cfg(target_os = "android")]
device_config_class,
peer_client_info_class,
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
device_info_class,
})
}
}
impl CallBack {
fn success0(&self) -> jni::errors::Result<()> {
let env = &mut self.jvm.attach_current_thread()? as &mut JNIEnv;
let mut env = self.jvm.attach_current_thread_as_daemon()?;
env.call_method(&self.this, "success", "()V", &[])?;
Ok(())
}
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
fn create_tun0(&self, info: DeviceInfo) -> jni::errors::Result<()> {
let env = &mut self.jvm.attach_current_thread()? as &mut JNIEnv;
let mut env = self.jvm.attach_current_thread_as_daemon()?;
let class = unsafe { JClass::from_raw(self.device_info_class.as_raw()) };
let param = env.new_object(
"top/wherewego/vnt/jni/param/DeviceInfo",
class,
"(Ljava/lang/String;Ljava/lang/String;)V",
&[
JValue::Object(&env.new_string(info.name)?.into()),
@@ -50,9 +97,10 @@ impl CallBack {
Ok(())
}
fn connect0(&self, info: ConnectInfo) -> jni::errors::Result<()> {
let env = &mut self.jvm.attach_current_thread()? as &mut JNIEnv;
let mut env = self.jvm.attach_current_thread_as_daemon()?;
let class = unsafe { JClass::from_raw(self.connect_info_class.as_raw()) };
let param = env.new_object(
"top/wherewego/vnt/jni/param/ConnectInfo",
class,
"(JLjava/lang/String;)V",
&[
JValue::Long(info.count as _),
@@ -68,7 +116,7 @@ impl CallBack {
Ok(())
}
fn handshake0(&self, info: HandshakeInfo) -> jni::errors::Result<bool> {
let env = &mut self.jvm.attach_current_thread()? as &mut JNIEnv;
let mut env = self.jvm.attach_current_thread_as_daemon()?;
let public_key = if let Some(public_key) = info.public_key {
match public_key.to_public_key_pem(LineEnding::CRLF) {
Ok(public_key) => env.new_string(public_key)?,
@@ -85,8 +133,10 @@ impl CallBack {
} else {
JString::default()
};
let class = unsafe { JClass::from_raw(self.handshake_info_class.as_raw()) };
let param = env.new_object(
"top/wherewego/vnt/jni/param/HandshakeInfo",
class,
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V",
&[
JValue::Object(&public_key),
@@ -103,14 +153,15 @@ impl CallBack {
rs.z()
}
fn register0(&self, info: RegisterInfo) -> jni::errors::Result<bool> {
let env = &mut self.jvm.attach_current_thread()? as &mut JNIEnv;
let mut env = self.jvm.attach_current_thread_as_daemon()?;
let class = unsafe { JClass::from_raw(self.register_info_class.as_raw()) };
let param = env.new_object(
"top/wherewego/vnt/jni/param/RegisterInfo",
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V",
class,
"(III)V",
&[
JValue::Object(&env.new_string(info.virtual_ip.to_string())?.into()),
JValue::Object(&env.new_string(info.virtual_netmask.to_string())?.into()),
JValue::Object(&env.new_string(info.virtual_gateway.to_string())?.into()),
JValue::Int(u32::from(info.virtual_ip) as _),
JValue::Int(u32::from(info.virtual_netmask) as _),
JValue::Int(u32::from(info.virtual_gateway) as _),
],
)?;
let rs = env.call_method(
@@ -121,16 +172,78 @@ impl CallBack {
)?;
rs.z()
}
#[cfg(target_os = "android")]
fn generate_tun0(&self, info: DeviceConfig) -> jni::errors::Result<u32> {
let mut env = self.jvm.attach_current_thread_as_daemon()?;
let class = unsafe { JClass::from_raw(self.device_config_class.as_raw()) };
let object_array = env.new_object_array(
info.external_route.len() as _,
"java/lang/String",
JObject::null(),
)?;
for (index, (network, mask)) in info.external_route.into_iter().enumerate() {
let param =
env.new_string(format!("{}/{}", network, u32::from(mask).leading_ones()))?;
env.set_object_array_element(&object_array, index as _, &param)?;
}
let param = env.new_object(
class,
"(IIII[Ljava/lang/String;)V",
&[
JValue::Int(u32::from(info.virtual_ip) as _),
JValue::Int(u32::from(info.virtual_netmask) as _),
JValue::Int(u32::from(info.virtual_gateway) as _),
JValue::Int(u32::from(info.virtual_network) as _),
JValue::Object(&object_array),
],
)?;
let rs = env.call_method(
&self.this,
"generateTun",
"(Ltop/wherewego/vnt/jni/param/DeviceConfig;)I",
&[JValue::Object(&param)],
)?;
rs.i().map(|v| v as _)
}
fn peer_client_list0(&self, info_vec: Vec<PeerClientInfo>) -> jni::errors::Result<()> {
let mut env = self.jvm.attach_current_thread_as_daemon()?;
let class = unsafe { JClass::from_raw(self.peer_client_info_class.as_raw()) };
let object_array = env.new_object_array(info_vec.len() as _, &class, JObject::null())?;
for (index, info) in info_vec.into_iter().enumerate() {
let param = env.new_object(
&class,
"(ILjava/lang/String;ZZ)V",
&[
JValue::Int(u32::from(info.virtual_ip) as _),
JValue::Object(&env.new_string(info.name)?.into()),
JValue::Bool(info.status.is_online() as _),
JValue::Bool(info.client_secret as _),
],
)?;
env.set_object_array_element(&object_array, index as _, &param)?;
}
env.call_method(
&self.this,
"peerClientList",
"([Ltop/wherewego/vnt/jni/param/PeerClientInfo;)V",
&[JValue::Object(&object_array)],
)?;
Ok(())
}
fn error0(&self, info: ErrorInfo) -> jni::errors::Result<()> {
let code: u8 = info.code.into();
let env = &mut self.jvm.attach_current_thread()? as &mut JNIEnv;
let mut env = self.jvm.attach_current_thread_as_daemon()?;
let class = unsafe { JClass::from_raw(self.error_info_class.as_raw()) };
let msg = if let Some(msg) = info.msg {
env.new_string(msg)?
} else {
JString::default()
};
let param = env.new_object(
"top/wherewego/vnt/jni/param/ErrorInfo",
class,
"(ILjava/lang/String;)V",
&[JValue::Int(code as _), JValue::Object(&msg.into())],
)?;
@@ -143,7 +256,7 @@ impl CallBack {
Ok(())
}
fn stop0(&self) -> jni::errors::Result<()> {
let env = &mut self.jvm.attach_current_thread()? as &mut JNIEnv;
let mut env = self.jvm.attach_current_thread_as_daemon()?;
env.call_method(&self.this, "stop", "()V", &[])?;
Ok(())
}
@@ -155,6 +268,7 @@ impl VntCallback for CallBack {
log::warn!("success {:?}", e);
}
}
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
fn create_tun(&self, info: DeviceInfo) {
if let Err(e) = self.create_tun0(info) {
log::warn!("create_tun {:?}", e);
@@ -180,6 +294,19 @@ impl VntCallback for CallBack {
false
})
}
#[cfg(target_os = "android")]
fn generate_tun(&self, info: DeviceConfig) -> u32 {
self.generate_tun0(info).unwrap_or_else(|e| {
log::warn!("generate_tun {:?}", e);
0
})
}
fn peer_client_list(&self, info: Vec<PeerClientInfo>) {
if let Err(e) = self.peer_client_list0(info) {
log::warn!("peer_client_list {:?}", e);
}
}
fn error(&self, info: ErrorInfo) {
if let Err(e) = self.error0(info) {
+2 -25
View File
@@ -1,4 +1,3 @@
use std::net::ToSocketAddrs;
use std::str::FromStr;
use jni::errors::Error;
@@ -21,6 +20,7 @@ pub fn new_config(env: &mut JNIEnv, config: JObject) -> Result<Config, Error> {
let password = to_string(env, &config, "password")?;
let server_address_str = to_string_not_null(env, &config, "server")?;
let stun_server = to_string_array_not_null(env, &config, "stunServer")?;
let dns = to_string_array(env, &config, "dns")?.unwrap_or_else(|| vec![]);
let cipher_model = to_string_not_null(env, &config, "cipherModel")?;
let punch_model = to_string(env, &config, "punchModel")?;
let mtu = to_integer(env, &config, "mtu")?.map(|v| v as u32);
@@ -78,25 +78,6 @@ pub fn new_config(env: &mut JNIEnv, config: JObject) -> Result<Config, Error> {
vec![]
};
let server_address = match server_address_str.to_socket_addrs() {
Ok(mut rs) => {
if let Some(addr) = rs.next() {
addr
} else {
env.throw_new("java/lang/RuntimeException", "server address err")
.expect("throw");
return Err(Error::JavaException);
}
}
Err(e) => {
env.throw_new(
"java/lang/RuntimeException",
format!("server address {}", e),
)
.expect("throw");
return Err(Error::JavaException);
}
};
let cipher_model = match CipherModel::from_str(&cipher_model) {
Ok(cipher_model) => cipher_model,
Err(e) => {
@@ -107,16 +88,14 @@ pub fn new_config(env: &mut JNIEnv, config: JObject) -> Result<Config, Error> {
};
#[cfg(not(target_os = "android"))]
let device_name = to_string(env, &config, "deviceName")?;
#[cfg(target_os = "android")]
let device_fd = env.get_field(&config, "deviceFd", "I")?.i()? as i32;
let config = match Config::new(
#[cfg(any(target_os = "windows", target_os = "linux"))]
tap,
token,
device_id,
name,
server_address,
server_address_str,
dns,
stun_server,
in_ips,
out_ips,
@@ -134,8 +113,6 @@ pub fn new_config(env: &mut JNIEnv, config: JObject) -> Result<Config, Error> {
first_latency,
#[cfg(not(target_os = "android"))]
device_name,
#[cfg(target_os = "android")]
device_fd,
UseChannelType::from_str(&use_channel.unwrap_or_default()).unwrap_or_default(),
packet_loss_rate,
packet_delay,
+16 -11
View File
@@ -2,7 +2,7 @@ use std::ptr;
use jni::errors::Error;
use jni::objects::{JClass, JObject, JValue};
use jni::sys::{jbyte, jint, jlong, jobject, jobjectArray, jsize};
use jni::sys::{jint, jlong, jobject, jobjectArray, jsize};
use jni::JNIEnv;
use vnt::channel::Route;
@@ -30,7 +30,13 @@ pub unsafe extern "C" fn Java_top_wherewego_vnt_jni_Vnt_new0(
} else {
return 0;
};
let vnt_util = match Vnt::new(config, CallBack::new(jvm, call_back)) {
let call_back = match CallBack::new(jvm, call_back) {
Ok(call_back) => call_back,
Err(_) => {
return 0;
}
};
let vnt_util = match Vnt::new(config, call_back) {
Ok(vnt_util) => vnt_util,
Err(e) => {
env.throw_new(
@@ -58,6 +64,7 @@ pub unsafe extern "C" fn Java_top_wherewego_vnt_jni_Vnt_stop0(
let vnt = raw_vnt as *mut Vnt;
let _ = (&*vnt).stop();
}
#[no_mangle]
pub unsafe extern "C" fn Java_top_wherewego_vnt_jni_Vnt_wait0(
_env: JNIEnv,
@@ -90,7 +97,7 @@ pub unsafe extern "C" fn Java_top_wherewego_vnt_jni_Vnt_list0(
let arr = match env.new_object_array(
list.len() as jsize,
"top/wherewego/vnt/jni/PeerDeviceInfo",
"top/wherewego/vnt/jni/PeerRouteInfo",
JObject::null(),
) {
Ok(arr) => arr,
@@ -131,16 +138,14 @@ pub unsafe extern "C" fn Java_top_wherewego_vnt_jni_Vnt_list0(
}
fn route_parse(env: &mut JNIEnv, route: Route) -> Result<jobject, Error> {
let address = route.addr.to_string();
let metric = route.metric;
let rt = route.rt;
let rs = env.new_object(
"top/wherewego/vnt/jni/Route",
"(Ljava/lang/String;BI)V",
"(ZLjava/lang/String;BI)V",
&[
JValue::Object(&env.new_string(address)?.into()),
JValue::Byte(metric as jbyte),
JValue::Int(rt as jint),
JValue::Bool(route.is_tcp as _),
JValue::Object(&env.new_string(route.addr.to_string())?.into()),
JValue::Byte(route.metric as _),
JValue::Int(route.rt as _),
],
)?;
Ok(rs.as_raw())
@@ -155,7 +160,7 @@ fn peer_device_info_parse(
let name = peer.name.to_string();
let status = format!("{:?}", peer.status);
let rs = env.new_object(
"top/wherewego/vnt/jni/PeerDeviceInfo",
"top/wherewego/vnt/jni/PeerRouteInfo",
"(ILjava/lang/String;Ljava/lang/String;Ltop/wherewego/vnt/jni/Route;)V",
&[
JValue::Int(virtual_ip as jint),
+3
View File
@@ -31,6 +31,9 @@ openssl-sys = { git = "https://github.com/lbl8603/rust-openssl" ,optional = true
libsm = {git="https://github.com/lbl8603/libsm" ,optional = true}
mio = {version = "0.8.10",features = ["os-poll","net"]}
crossbeam-queue = "0.3.11"
anyhow = "1.0.82"
dns-parser = "0.8.0"
[target.'cfg(target_os = "windows")'.dependencies]
libloading = "0.8.0"
+3
View File
@@ -3,6 +3,7 @@ syntax = "proto3";
message HandshakeRequest {
string version = 1;
bool secret = 2;
string key_finger = 3;
}
message HandshakeResponse {
string version = 1;
@@ -23,6 +24,7 @@ message RegistrationRequest {
fixed32 virtual_ip = 6;
bool allow_ip_change = 7;
bool client_secret = 8;
bytes client_secret_hash = 9;
}
message RegistrationResponse {
@@ -40,6 +42,7 @@ message DeviceInfo {
fixed32 virtual_ip = 2;
uint32 device_status = 3;
bool client_secret = 4;
bytes client_secret_hash = 5;
}
message DeviceList {
+14 -3
View File
@@ -16,11 +16,11 @@ use crate::channel::{Route, RouteKey, UseChannelType, DEFAULT_RT};
/// 传输通道上下文,持有udp socket、tcp socket和路由信息
#[derive(Clone)]
pub struct Context {
pub struct ChannelContext {
inner: Arc<ContextInner>,
}
impl Context {
impl ChannelContext {
pub fn new(
main_udp_socket: Vec<UdpSocket>,
use_channel_type: UseChannelType,
@@ -63,7 +63,7 @@ impl Context {
}
}
impl Deref for Context {
impl Deref for ChannelContext {
type Target = ContextInner;
fn deref(&self) -> &Self::Target {
@@ -74,6 +74,7 @@ impl Deref for Context {
/// 对称网络增加的udp socket数目,有助于增加打洞成功率
pub const SYMMETRIC_CHANNEL_NUM: usize = 100;
const PACKET_LOSS_RATE_DENOMINATOR: u32 = 100_0000;
pub struct ContextInner {
// 核心udp socket
pub(crate) main_udp_socket: Vec<UdpSocket>,
@@ -198,6 +199,7 @@ impl ContextInner {
self.send_main_udp(self.main_index.load(Ordering::Relaxed), buf, addr)
}
}
pub fn change_main_index(&self) {
let index = (self.main_index.load(Ordering::Relaxed) + 1) % self.main_udp_socket.len();
self.main_index.store(index, Ordering::Relaxed);
@@ -345,6 +347,15 @@ impl RouteTable {
_ => {}
}
let key = route.route_key();
if only_if_absent {
if let Some((_, list)) = self.route_table.read().get(&id) {
for (x, _) in list {
if x.route_key() == key {
return;
}
}
}
}
let mut route_table = self.route_table.write();
let (_, list) = route_table
.entry(id)
+2 -2
View File
@@ -1,6 +1,6 @@
use crate::channel::context::Context;
use crate::channel::context::ChannelContext;
use crate::channel::RouteKey;
pub trait RecvChannelHandler: Clone + Send + 'static {
fn handle(&mut self, buf: &mut [u8], route_key: RouteKey, context: &Context);
fn handle(&mut self, buf: &mut [u8], route_key: RouteKey, context: &ChannelContext);
}
+3 -3
View File
@@ -1,16 +1,16 @@
use std::net::Ipv4Addr;
use std::time::Duration;
use crate::channel::context::Context;
use crate::channel::context::ChannelContext;
use crate::channel::Route;
pub struct Idle {
read_idle: Duration,
context: Context,
context: ChannelContext,
}
impl Idle {
pub fn new(read_idle: Duration, context: Context) -> Self {
pub fn new(read_idle: Duration, context: ChannelContext) -> Self {
Self { read_idle, context }
}
}
+4 -10
View File
@@ -2,7 +2,7 @@ use std::io;
use std::net::{SocketAddr, UdpSocket};
use std::str::FromStr;
use crate::channel::context::Context;
use crate::channel::context::ChannelContext;
use crate::channel::handler::RecvChannelHandler;
use crate::channel::sender::AcceptSocketSender;
use crate::channel::tcp_channel::tcp_listen;
@@ -53,12 +53,6 @@ impl Default for UseChannelType {
UseChannelType::All
}
}
#[derive(Copy, Clone, Eq, PartialEq)]
pub enum Status {
Cone,
Symmetric,
Close,
}
#[derive(Copy, Clone, Debug)]
pub struct Route {
@@ -151,7 +145,7 @@ pub fn init_context(
is_tcp: bool,
packet_loss_rate: Option<f64>,
packet_delay: u32,
) -> io::Result<(Context, mio::net::TcpListener)> {
) -> io::Result<(ChannelContext, mio::net::TcpListener)> {
assert!(!ports.is_empty(), "not channel");
let mut udps = Vec::with_capacity(ports.len());
//检查系统是否支持ipv6
@@ -191,7 +185,7 @@ pub fn init_context(
let main_channel: UdpSocket = socket.into();
udps.push(main_channel);
}
let context = Context::new(
let context = ChannelContext::new(
udps,
use_channel_type,
first_latency,
@@ -242,7 +236,7 @@ pub fn init_context(
pub fn init_channel<H>(
tcp_listener: mio::net::TcpListener,
context: Context,
context: ChannelContext,
stop_manager: StopManager,
recv_handler: H,
) -> io::Result<(
+37 -9
View File
@@ -8,8 +8,10 @@ use mio::net::TcpStream;
use rand::prelude::SliceRandom;
use rand::Rng;
use crate::channel::context::Context;
use crate::channel::context::ChannelContext;
use crate::channel::sender::AcceptSocketSender;
use crate::external_route::ExternalRoute;
use crate::nat::NatTest;
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub enum PunchModel {
@@ -179,20 +181,24 @@ impl NatInfo {
#[derive(Clone)]
pub struct Punch {
context: Context,
context: ChannelContext,
port_vec: Vec<u16>,
port_index: HashMap<Ipv4Addr, usize>,
punch_model: PunchModel,
is_tcp: bool,
tcp_socket_sender: AcceptSocketSender<(TcpStream, SocketAddr, Option<Vec<u8>>)>,
external_route: ExternalRoute,
nat_test: NatTest,
}
impl Punch {
pub fn new(
context: Context,
context: ChannelContext,
punch_model: PunchModel,
is_tcp: bool,
tcp_socket_sender: AcceptSocketSender<(TcpStream, SocketAddr, Option<Vec<u8>>)>,
external_route: ExternalRoute,
nat_test: NatTest,
) -> Self {
let mut port_vec: Vec<u16> = (1..65535).collect();
port_vec.push(65535);
@@ -205,12 +211,17 @@ impl Punch {
punch_model,
is_tcp,
tcp_socket_sender,
external_route,
nat_test,
}
}
}
impl Punch {
fn connect_tcp(&self, buf: &[u8], addr: SocketAddr) -> bool {
if self.nat_test.is_local_address(true, addr) {
return false;
}
// mio是非阻塞的,不能立马判断是否能连接成功,所以用标准库的tcp
match std::net::TcpStream::connect_timeout(&addr, Duration::from_millis(100)) {
Ok(tcp_stream) => {
@@ -232,13 +243,26 @@ impl Punch {
&mut self,
buf: &[u8],
id: Ipv4Addr,
nat_info: NatInfo,
mut nat_info: NatInfo,
punch_tcp: bool,
) -> io::Result<()> {
if self.context.route_table.no_need_punch(&id) {
log::info!("已打洞成功,无需打洞:{:?}", id);
return Ok(());
}
nat_info
.public_ips
.retain(|ip| self.external_route.route(&ip).is_none());
nat_info
.local_ipv4
.filter(|ip| self.external_route.route(&ip).is_none());
nat_info.ipv6.filter(|ip| {
if let Some(ip) = ip.to_ipv4_mapped() {
self.external_route.route(&ip).is_none()
} else {
true
}
});
if punch_tcp && self.is_tcp && nat_info.tcp_port != 0 {
//向tcp发起连接
if let Some(ipv6_addr) = nat_info.local_tcp_ipv6addr() {
@@ -263,17 +287,21 @@ impl Punch {
let channel_num = self.context.channel_num();
for index in 0..channel_num {
if let Some(ipv4_addr) = nat_info.local_udp_ipv4addr(index) {
let _ = self.context.send_main_udp(index, buf, ipv4_addr);
if !self.nat_test.is_local_address(false, ipv4_addr) {
let _ = self.context.send_main_udp(index, buf, ipv4_addr);
}
}
}
if self.punch_model != PunchModel::IPv4 {
for index in 0..channel_num {
if let Some(ipv6_addr) = nat_info.local_udp_ipv6addr(index) {
let rs = self.context.send_main_udp(index, buf, ipv6_addr);
log::info!("发送到ipv6地址:{:?},rs={:?}", ipv6_addr, rs);
if rs.is_ok() && self.punch_model == PunchModel::IPv6 {
return Ok(());
if !self.nat_test.is_local_address(false, ipv6_addr) {
let rs = self.context.send_main_udp(index, buf, ipv6_addr);
log::info!("发送到ipv6地址:{:?},rs={:?}", ipv6_addr, rs);
if rs.is_ok() && self.punch_model == PunchModel::IPv6 {
return Ok(());
}
}
}
}
+4 -4
View File
@@ -5,22 +5,22 @@ use std::sync::Arc;
use mio::Token;
use crate::channel::context::Context;
use crate::channel::context::ChannelContext;
use crate::channel::notify::{AcceptNotify, WritableNotify};
#[derive(Clone)]
pub struct ChannelSender {
context: Context,
context: ChannelContext,
}
impl ChannelSender {
pub fn new(context: Context) -> Self {
pub fn new(context: ChannelContext) -> Self {
Self { context }
}
}
impl Deref for ChannelSender {
type Target = Context;
type Target = ChannelContext;
fn deref(&self) -> &Self::Target {
&self.context
+7 -7
View File
@@ -15,7 +15,7 @@ use std::{io, thread};
use mio::net::{TcpListener, TcpStream};
use mio::{Events, Interest, Poll, Registry, Token, Waker};
use crate::channel::context::Context;
use crate::channel::context::ChannelContext;
use crate::channel::handler::RecvChannelHandler;
use crate::channel::notify::{AcceptNotify, WritableNotify};
use crate::channel::sender::{AcceptSocketSender, PacketSender};
@@ -30,7 +30,7 @@ pub fn tcp_listen<H>(
tcp_server: TcpListener,
stop_manager: StopManager,
recv_handler: H,
context: Context,
context: ChannelContext,
) -> io::Result<AcceptSocketSender<(TcpStream, SocketAddr, Option<Vec<u8>>)>>
where
H: RecvChannelHandler,
@@ -74,7 +74,7 @@ fn tcp_listen0<H>(
accept_notify: AcceptNotify,
accept_tcp_receiver: Receiver<(TcpStream, SocketAddr, Option<Vec<u8>>)>,
mut recv_handler: H,
context: Context,
context: ChannelContext,
) -> io::Result<()>
where
H: RecvChannelHandler,
@@ -158,7 +158,7 @@ where
fn init_writable_handler(
receiver: Receiver<(TcpStream, Token, SocketAddr, Option<Vec<u8>>)>,
stop_manager: StopManager,
context: Context,
context: ChannelContext,
) -> io::Result<WritableNotify> {
let poll = Poll::new()?;
let writable_notify = WritableNotify::new(Waker::new(poll.registry(), NOTIFY)?);
@@ -190,7 +190,7 @@ fn tcp_writable_listen(
receiver: Receiver<(TcpStream, Token, SocketAddr, Option<Vec<u8>>)>,
mut poll: Poll,
writable_notify: WritableNotify,
context: &Context,
context: &ChannelContext,
) -> io::Result<()> {
let mut events = Events::with_capacity(1024);
let mut write_map: HashMap<
@@ -338,7 +338,7 @@ fn readable_handle<H>(
token: &Token,
map: &mut HashMap<Token, (RouteKey, TcpStream, Box<[u8; BUFFER_SIZE]>, usize)>,
recv_handler: &mut H,
context: &Context,
context: &ChannelContext,
) -> io::Result<()>
where
H: RecvChannelHandler,
@@ -447,7 +447,7 @@ fn closed_handle_w(
Option<(Vec<u8>, usize)>,
),
>,
context: &Context,
context: &ChannelContext,
) {
if let Some((tcp, addr, _, _)) = map.remove(token) {
context.tcp_map.write().remove(&addr);
+10 -6
View File
@@ -6,7 +6,7 @@ use mio::event::Source;
use mio::net::UdpSocket;
use mio::{Events, Interest, Poll, Token, Waker};
use crate::channel::context::Context;
use crate::channel::context::ChannelContext;
use crate::channel::handler::RecvChannelHandler;
use crate::channel::notify::AcceptNotify;
use crate::channel::sender::AcceptSocketSender;
@@ -16,7 +16,7 @@ use crate::util::StopManager;
pub fn udp_listen<H>(
stop_manager: StopManager,
recv_handler: H,
context: Context,
context: ChannelContext,
) -> io::Result<AcceptSocketSender<Option<Vec<UdpSocket>>>>
where
H: RecvChannelHandler,
@@ -30,7 +30,7 @@ const NOTIFY: Token = Token(0);
fn sub_udp_listen<H>(
stop_manager: StopManager,
recv_handler: H,
context: Context,
context: ChannelContext,
) -> io::Result<AcceptSocketSender<Option<Vec<UdpSocket>>>>
where
H: RecvChannelHandler,
@@ -61,7 +61,7 @@ where
fn sub_udp_listen0<H>(
mut poll: Poll,
mut recv_handler: H,
context: Context,
context: ChannelContext,
accept_notify: AcceptNotify,
accept_receiver: Receiver<Option<Vec<UdpSocket>>>,
) -> io::Result<()>
@@ -205,7 +205,7 @@ where
fn main_udp_listen<H>(
stop_manager: StopManager,
recv_handler: H,
context: Context,
context: ChannelContext,
) -> io::Result<()>
where
H: RecvChannelHandler,
@@ -231,7 +231,11 @@ where
Ok(())
}
pub fn main_udp_listen0<H>(mut poll: Poll, mut recv_handler: H, context: Context) -> io::Result<()>
pub fn main_udp_listen0<H>(
mut poll: Poll,
mut recv_handler: H,
context: ChannelContext,
) -> io::Result<()>
where
H: RecvChannelHandler,
{
+13
View File
@@ -1,6 +1,7 @@
#[cfg(feature = "aes_ecb")]
#[cfg(not(any(feature = "openssl-vendored", feature = "openssl")))]
use crate::cipher::aes_ecb::AesEcbCipher;
use std::fmt::Display;
#[cfg(feature = "aes_cbc")]
use crate::cipher::aes_cbc::AesCbcCipher;
@@ -48,6 +49,18 @@ pub enum CipherModel {
None,
}
impl Display for CipherModel {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let str = match self {
CipherModel::AesGcm => "aes_gcm".to_string(),
CipherModel::AesCbc => "aes_cbc".to_string(),
CipherModel::AesEcb => "aes_ecb".to_string(),
CipherModel::Sm4Cbc => "sm4_cbc".to_string(),
CipherModel::None => "none".to_string(),
};
write!(f, "{}", str)
}
}
impl FromStr for CipherModel {
type Err = String;
+25 -19
View File
@@ -1,5 +1,5 @@
use crate::protocol::NetPacket;
use std::io;
use {
crate::protocol::body::{RsaSecretBody, RSA_ENCRYPTION_RESERVED},
rand::Rng,
@@ -9,6 +9,8 @@ use {
spki::{DecodePublicKey, EncodePublicKey},
};
use crate::protocol::NetPacket;
#[derive(Clone)]
pub struct RsaCipher {
inner: Inner,
@@ -16,13 +18,15 @@ pub struct RsaCipher {
#[derive(Clone)]
struct Inner {
public_key: RsaPublicKey,
finger: String,
}
impl RsaCipher {
pub fn new(der: &[u8]) -> io::Result<Self> {
match RsaPublicKey::from_public_key_der(der) {
Ok(public_key) => {
let inner = Inner { public_key };
let finger = finger(&public_key)?;
let inner = Inner { public_key, finger };
Ok(Self { inner })
}
Err(e) => Err(io::Error::new(
@@ -31,30 +35,32 @@ impl RsaCipher {
)),
}
}
pub fn finger(&self) -> io::Result<String> {
match self.inner.public_key.to_public_key_der() {
Ok(der) => match rsa::pkcs8::SubjectPublicKeyInfoRef::from_der(der.as_bytes()) {
Ok(spki) => match spki.fingerprint_base64() {
Ok(finger) => Ok(finger),
Err(e) => Err(io::Error::new(
io::ErrorKind::Other,
format!("fingerprint_base64 error {}", e),
)),
},
pub fn finger(&self) -> &String {
&self.inner.finger
}
pub fn public_key(&self) -> io::Result<&RsaPublicKey> {
return Ok(&self.inner.public_key);
}
}
pub fn finger(public_key: &RsaPublicKey) -> io::Result<String> {
match public_key.to_public_key_der() {
Ok(der) => match rsa::pkcs8::SubjectPublicKeyInfoRef::from_der(der.as_bytes()) {
Ok(spki) => match spki.fingerprint_base64() {
Ok(finger) => Ok(finger),
Err(e) => Err(io::Error::new(
io::ErrorKind::Other,
format!("from_der error {}", e),
format!("fingerprint_base64 error {}", e),
)),
},
Err(e) => Err(io::Error::new(
io::ErrorKind::Other,
format!("to_public_key_der error {}", e),
format!("from_der error {}", e),
)),
}
}
pub fn public_key(&self) -> io::Result<&RsaPublicKey> {
return Ok(&self.inner.public_key);
},
Err(e) => Err(io::Error::new(
io::ErrorKind::Other,
format!("to_public_key_der error {}", e),
)),
}
}
+62 -31
View File
@@ -7,10 +7,11 @@ use std::time::Duration;
use crossbeam_utils::atomic::AtomicCell;
use parking_lot::{Mutex, RwLock};
use rand::Rng;
use rsa::signature::digest::Digest;
#[cfg(not(target_os = "android"))]
use tun::device::IFace;
use crate::channel::context::Context;
use crate::channel::context::ChannelContext;
use crate::channel::idle::Idle;
use crate::channel::punch::{NatInfo, Punch};
use crate::channel::{init_channel, init_context, Route, RouteKey};
@@ -22,14 +23,15 @@ use crate::external_route::{AllowExternalRoute, ExternalRoute};
use crate::handle::handshaker::Handshake;
use crate::handle::maintain::PunchReceiver;
use crate::handle::recv_data::RecvDataHandler;
use crate::handle::{
maintain, tun_tap, BaseConfigInfo, ConnectStatus, CurrentDeviceInfo, PeerDeviceInfo,
};
use crate::handle::{maintain, BaseConfigInfo, ConnectStatus, CurrentDeviceInfo, PeerDeviceInfo};
use crate::nat::NatTest;
use crate::tun_tap_device::tun_create_helper::{DeviceAdapter, TunDeviceHelper};
use crate::util::{
Scheduler, SingleU64Adder, StopManager, U64Adder, WatchSingleU64Adder, WatchU64Adder,
};
use crate::{nat, tun_tap_device, DeviceInfo, VntCallback};
use crate::{nat, VntCallback};
#[cfg(not(target_os = "android"))]
use crate::{tun_tap_device, DeviceInfo};
#[derive(Clone)]
pub struct Vnt {
@@ -38,10 +40,11 @@ pub struct Vnt {
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
nat_test: NatTest,
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
context: Context,
context: ChannelContext,
peer_nat_info_map: Arc<RwLock<HashMap<Ipv4Addr, NatInfo>>>,
down_count_watcher: WatchU64Adder,
up_count_watcher: WatchSingleU64Adder,
client_secret_hash: Option<[u8; 16]>,
}
impl Vnt {
@@ -78,9 +81,18 @@ impl Vnt {
config.name.clone(),
config.token.clone(),
config.ip,
config.password.is_some(),
config.password.as_ref().map(|v| {
let mut hasher = sha2::Sha256::new();
hasher.update(config.cipher_model.to_string().as_bytes());
hasher.update(v.as_bytes());
hasher.update(config.token.as_bytes());
let key: [u8; 32] = hasher.finalize().into();
key[16..].try_into().unwrap()
}),
config.server_encrypt,
config.device_id.clone(),
config.server_address_str.clone(),
config.name_servers.clone(),
);
let ports = config.ports.as_ref().map_or(vec![0, 0], |v| {
if v.is_empty() {
@@ -112,10 +124,14 @@ impl Vnt {
tcp_port,
);
// 虚拟网卡
let device = tun_tap_device::create_device(&config)?;
let tun_info = DeviceInfo::new(device.name()?, device.version()?);
callback.create_tun(tun_info);
// pc上先创建虚拟网卡
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
let device = {
let device = tun_tap_device::create_device(&config)?;
let tun_info = DeviceInfo::new(device.name()?, device.version()?);
callback.create_tun(tun_info);
device
};
// 服务停止管理器
let stop_manager = {
let callback = callback.clone();
@@ -144,14 +160,34 @@ impl Vnt {
let down_counter =
U64Adder::with_capacity(config.ports.as_ref().map(|v| v.len()).unwrap_or_default() + 8);
let down_count_watcher = down_counter.watch();
let handshake = Handshake::new();
let handshake = Handshake::new(rsa_cipher.clone());
let up_counter = SingleU64Adder::new();
let up_count_watcher = up_counter.watch();
let tun_helper = TunDeviceHelper::new(
stop_manager.clone(),
context.clone(),
current_device.clone(),
external_route.clone(),
#[cfg(feature = "ip_proxy")]
proxy_map.clone(),
client_cipher.clone(),
server_cipher.clone(),
config.parallel,
up_counter,
device_list.clone(),
);
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
let device_adapter = DeviceAdapter::new(device.clone());
#[cfg(target_os = "android")]
let device_adapter = DeviceAdapter::new(tun_helper);
let handler = RecvDataHandler::new(
#[cfg(feature = "server_encrypt")]
rsa_cipher,
server_cipher.clone(),
client_cipher.clone(),
current_device.clone(),
device.clone(),
device_adapter,
device_list.clone(),
config_info.clone(),
nat_test.clone(),
@@ -175,23 +211,13 @@ impl Vnt {
config.punch_model,
config.tcp,
tcp_socket_sender.clone(),
external_route.clone(),
nat_test.clone(),
);
let up_counter = SingleU64Adder::new();
let up_count_watcher = up_counter.watch();
tun_tap::tun_handler::start(
stop_manager.clone(),
context.clone(),
device.clone(),
current_device.clone(),
external_route,
#[cfg(feature = "ip_proxy")]
proxy_map,
client_cipher.clone(),
server_cipher.clone(),
config.parallel,
up_counter,
device_list.clone(),
)?;
#[cfg(not(target_os = "android"))]
tun_helper.start(device)?;
maintain::idle_gateway(
&scheduler,
context.clone(),
@@ -208,6 +234,7 @@ impl Vnt {
let device_list = device_list.clone();
let down_count_watcher = down_count_watcher.clone();
let up_count_watcher = up_count_watcher.clone();
let config_info = config_info.clone();
let current_device = current_device.clone();
if !config.use_channel_type.is_only_relay() {
// 定时nat探测
@@ -248,13 +275,14 @@ impl Vnt {
peer_nat_info_map,
down_count_watcher,
up_count_watcher,
client_secret_hash: config_info.client_secret_hash,
})
}
}
pub fn start<Call: VntCallback>(
scheduler: &Scheduler,
context: Context,
context: ChannelContext,
nat_test: NatTest,
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
@@ -336,6 +364,9 @@ impl Vnt {
pub fn client_encrypt(&self) -> bool {
self.config.password.is_some()
}
pub fn client_encrypt_hash(&self) -> Option<&[u8]> {
self.client_secret_hash.as_ref().map(|v| v.as_ref())
}
pub fn current_device(&self) -> CurrentDeviceInfo {
self.current_device.load()
}
+20 -12
View File
@@ -1,11 +1,13 @@
use std::io;
use std::net::{Ipv4Addr, SocketAddr};
use anyhow::anyhow;
use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr};
use std::str::FromStr;
pub use conn::Vnt;
use crate::channel::punch::PunchModel;
use crate::channel::UseChannelType;
use crate::cipher::CipherModel;
use crate::util::{address_choose, dns_query_all};
mod conn;
@@ -18,6 +20,7 @@ pub struct Config {
pub name: String,
pub server_address: SocketAddr,
pub server_address_str: String,
pub name_servers: Vec<String>,
pub stun_server: Vec<String>,
pub in_ips: Vec<(u32, u32, Ipv4Addr)>,
pub out_ips: Vec<(u32, u32)>,
@@ -36,8 +39,6 @@ pub struct Config {
pub first_latency: bool,
#[cfg(not(target_os = "android"))]
pub device_name: Option<String>,
#[cfg(target_os = "android")]
pub device_fd: i32,
pub use_channel_type: UseChannelType,
//控制丢包率
pub packet_loss_rate: Option<f64>,
@@ -50,8 +51,8 @@ impl Config {
token: String,
device_id: String,
name: String,
server_address: SocketAddr,
server_address_str: String,
mut name_servers: Vec<String>,
mut stun_server: Vec<String>,
in_ips: Vec<(u32, u32, Ipv4Addr)>,
out_ips: Vec<(u32, u32)>,
@@ -68,25 +69,33 @@ impl Config {
ports: Option<Vec<u16>>,
first_latency: bool,
#[cfg(not(target_os = "android"))] device_name: Option<String>,
#[cfg(target_os = "android")] device_fd: i32,
use_channel_type: UseChannelType,
packet_loss_rate: Option<f64>,
packet_delay: u32,
) -> io::Result<Self> {
) -> anyhow::Result<Self> {
for x in stun_server.iter_mut() {
if !x.contains(":") {
x.push_str(":3478");
}
}
for x in name_servers.iter_mut() {
if Ipv6Addr::from_str(x).is_ok() {
x.push_str(":53");
} else if !x.contains(":") {
x.push_str(":53");
}
}
if token.is_empty() || token.len() > 128 {
return Err(io::Error::new(io::ErrorKind::Other, "token too long"));
return Err(anyhow!("token too long"));
}
if device_id.is_empty() || device_id.len() > 128 {
return Err(io::Error::new(io::ErrorKind::Other, "device_id too long"));
return Err(anyhow!("device_id too long"));
}
if name.is_empty() || name.len() > 128 {
return Err(io::Error::new(io::ErrorKind::Other, "name too long"));
return Err(anyhow!("name too long"));
}
let server_address =
address_choose(dns_query_all(&server_address_str, name_servers.clone())?)?;
Ok(Self {
#[cfg(any(target_os = "windows", target_os = "linux"))]
tap,
@@ -95,6 +104,7 @@ impl Config {
name,
server_address,
server_address_str,
name_servers,
stun_server,
in_ips,
out_ips,
@@ -113,8 +123,6 @@ impl Config {
first_latency,
#[cfg(not(target_os = "android"))]
device_name,
#[cfg(target_os = "android")]
device_fd,
use_channel_type,
packet_loss_rate,
packet_delay,
+89
View File
@@ -1,21 +1,25 @@
use crate::handle::PeerDeviceStatus;
#[cfg(feature = "server_encrypt")]
use rsa::RsaPublicKey;
use std::fmt::{Display, Formatter};
use std::io;
use std::net::{Ipv4Addr, SocketAddr};
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
#[derive(Debug)]
pub struct DeviceInfo {
pub name: String,
pub version: String,
}
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
impl Display for DeviceInfo {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.write_str(&format!("name={} ,version={}", self.name, self.version))
}
}
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
impl DeviceInfo {
pub fn new(name: String, version: String) -> Self {
return Self { name, version };
@@ -68,6 +72,7 @@ impl Display for HandshakeInfo {
f.write_str(&format!("server version={}", self.version))
}
}
#[cfg(feature = "server_encrypt")]
impl HandshakeInfo {
pub fn new(public_key: RsaPublicKey, finger: String, version: String) -> Self {
@@ -85,6 +90,7 @@ impl HandshakeInfo {
}
}
}
#[cfg(not(feature = "server_encrypt"))]
impl HandshakeInfo {
pub fn new_no_secret(version: String) -> Self {
@@ -183,11 +189,89 @@ impl Into<u8> for ErrorType {
}
}
#[cfg(target_os = "android")]
#[derive(Debug)]
pub struct DeviceConfig {
//本机虚拟IP
pub virtual_ip: Ipv4Addr,
//子网掩码
pub virtual_netmask: Ipv4Addr,
//虚拟网关
pub virtual_gateway: Ipv4Addr,
//虚拟网段
pub virtual_network: Ipv4Addr,
// 额外的路由
pub external_route: Vec<(Ipv4Addr, Ipv4Addr)>,
}
#[cfg(target_os = "android")]
impl DeviceConfig {
pub fn new(
virtual_ip: Ipv4Addr,
virtual_netmask: Ipv4Addr,
virtual_gateway: Ipv4Addr,
virtual_network: Ipv4Addr,
external_route: Vec<(Ipv4Addr, Ipv4Addr)>,
) -> Self {
Self {
virtual_ip,
virtual_netmask,
virtual_gateway,
virtual_network,
external_route,
}
}
}
#[cfg(target_os = "android")]
impl Display for DeviceConfig {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.write_str(&format!(
"ip={} ,netmask={} ,gateway={}, external_route={:?}",
self.virtual_ip, self.virtual_netmask, self.virtual_gateway, self.external_route
))
}
}
#[derive(Debug)]
pub struct PeerClientInfo {
pub virtual_ip: Ipv4Addr,
pub name: String,
pub status: PeerDeviceStatus,
pub client_secret: bool,
}
impl PeerClientInfo {
pub fn new(
virtual_ip: Ipv4Addr,
name: String,
status: PeerDeviceStatus,
client_secret: bool,
) -> Self {
Self {
virtual_ip,
name,
status,
client_secret,
}
}
}
impl Display for PeerClientInfo {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.write_str(&format!(
"ip={} ,name={} ,status={:?}, client_secret={}",
self.virtual_ip, self.name, self.status, self.client_secret
))
}
}
pub trait VntCallback: Clone + Send + Sync + 'static {
/// 启动成功
fn success(&self) {}
/// 创建网卡的信息
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
fn create_tun(&self, _info: DeviceInfo) {}
/// 连接
fn connect(&self, _info: ConnectInfo) {}
@@ -199,6 +283,11 @@ pub trait VntCallback: Clone + Send + Sync + 'static {
fn register(&self, _info: RegisterInfo) -> bool {
true
}
#[cfg(target_os = "android")]
fn generate_tun(&self, _info: DeviceConfig) -> u32 {
0
}
fn peer_client_list(&self, _info: Vec<PeerClientInfo>) {}
/// 异常信息
fn error(&self, _info: ErrorInfo) {}
/// 服务停止
+35 -30
View File
@@ -4,9 +4,10 @@ use std::sync::Arc;
use std::time::{Duration, Instant};
use crossbeam_utils::atomic::AtomicCell;
use parking_lot::Mutex;
use protobuf::Message;
use crate::channel::context::Context;
use crate::channel::context::ChannelContext;
#[cfg(feature = "server_encrypt")]
use crate::cipher::RsaCipher;
use crate::handle::{GATEWAY_IP, SELF_IP};
@@ -15,7 +16,7 @@ use crate::proto::message::HandshakeRequest;
use crate::proto::message::SecretHandshakeRequest;
#[cfg(feature = "server_encrypt")]
use crate::protocol::body::RSA_ENCRYPTION_RESERVED;
use crate::protocol::{service_packet, NetPacket, Protocol, Version, MAX_TTL};
use crate::protocol::{service_packet, NetPacket, Protocol, MAX_TTL};
pub enum HandshakeEnum {
NotSecret,
@@ -27,49 +28,53 @@ pub enum HandshakeEnum {
#[derive(Clone)]
pub struct Handshake {
time: Arc<AtomicCell<Instant>>,
rsa_cipher: Arc<Mutex<Option<RsaCipher>>>,
}
impl Handshake {
pub fn new() -> Self {
pub fn new(rsa_cipher: Arc<Mutex<Option<RsaCipher>>>) -> Self {
Handshake {
time: Arc::new(AtomicCell::new(Instant::now() - Duration::from_secs(60))),
rsa_cipher,
}
}
pub fn send(&self, context: &Context, secret: bool, addr: SocketAddr) -> io::Result<()> {
pub fn send(&self, context: &ChannelContext, secret: bool, addr: SocketAddr) -> io::Result<()> {
let last = self.time.load();
//短时间不重复发送
if last.elapsed() < Duration::from_secs(3) {
return Ok(());
}
let request_packet = handshake_request_packet(secret)?;
let request_packet = self.handshake_request_packet(secret)?;
log::info!("发送握手请求,secret={},{:?}", secret, addr);
context.send_default(request_packet.buffer(), addr)?;
self.time.store(Instant::now());
Ok(())
}
}
/// 第一次握手数据
pub fn handshake_request_packet(secret: bool) -> io::Result<NetPacket<Vec<u8>>> {
let mut request = HandshakeRequest::new();
request.secret = secret;
request.version = crate::VNT_VERSION.to_string();
let bytes = request.write_to_bytes().map_err(|e| {
io::Error::new(
io::ErrorKind::Other,
format!("handshake_request_packet {:?}", e),
)
})?;
let buf = vec![0u8; 12 + bytes.len()];
let mut net_packet = NetPacket::new(buf)?;
net_packet.set_version(Version::V1);
net_packet.set_gateway_flag(true);
net_packet.set_destination(GATEWAY_IP);
net_packet.set_source(SELF_IP);
net_packet.set_protocol(Protocol::Service);
net_packet.set_transport_protocol(service_packet::Protocol::HandshakeRequest.into());
net_packet.first_set_ttl(MAX_TTL);
net_packet.set_payload(&bytes)?;
Ok(net_packet)
/// 第一次握手数据
pub fn handshake_request_packet(&self, secret: bool) -> io::Result<NetPacket<Vec<u8>>> {
let mut request = HandshakeRequest::new();
request.secret = secret;
request.version = crate::VNT_VERSION.to_string();
if let Some(finger) = self.rsa_cipher.lock().as_ref().map(|v| v.finger().clone()) {
request.key_finger = finger;
}
let bytes = request.write_to_bytes().map_err(|e| {
io::Error::new(
io::ErrorKind::Other,
format!("handshake_request_packet {:?}", e),
)
})?;
let buf = vec![0u8; 12 + bytes.len()];
let mut net_packet = NetPacket::new(buf)?;
net_packet.set_default_version();
net_packet.set_gateway_flag(true);
net_packet.set_destination(GATEWAY_IP);
net_packet.set_source(SELF_IP);
net_packet.set_protocol(Protocol::Service);
net_packet.set_transport_protocol(service_packet::Protocol::HandshakeRequest.into());
net_packet.first_set_ttl(MAX_TTL);
net_packet.set_payload(&bytes)?;
Ok(net_packet)
}
}
/// 第二次加密握手
@@ -92,7 +97,7 @@ pub fn secret_handshake_request_packet(
12 + bytes.len(),
vec![0u8; 12 + bytes.len() + RSA_ENCRYPTION_RESERVED],
)?;
net_packet.set_version(Version::V1);
net_packet.set_default_version();
net_packet.set_gateway_flag(true);
net_packet.set_destination(GATEWAY_IP);
net_packet.set_source(SELF_IP);
+6 -6
View File
@@ -3,16 +3,16 @@ use std::time::Duration;
use crossbeam_utils::atomic::AtomicCell;
use crate::channel::context::Context;
use crate::channel::context::ChannelContext;
use crate::cipher::Cipher;
use crate::handle::{BaseConfigInfo, CurrentDeviceInfo};
use crate::protocol::body::ENCRYPTION_RESERVED;
use crate::protocol::{control_packet, NetPacket, Protocol, Version, MAX_TTL};
use crate::protocol::{control_packet, NetPacket, Protocol, MAX_TTL};
use crate::util::Scheduler;
pub fn addr_request(
scheduler: &Scheduler,
context: Context,
context: ChannelContext,
current_device_info: Arc<AtomicCell<CurrentDeviceInfo>>,
server_cipher: Cipher,
_config: BaseConfigInfo,
@@ -26,7 +26,7 @@ pub fn addr_request(
}
pub fn pub_address_request(
scheduler: &Scheduler,
context: Context,
context: ChannelContext,
current_device_info: Arc<AtomicCell<CurrentDeviceInfo>>,
server_cipher: Cipher,
) {
@@ -41,7 +41,7 @@ pub fn pub_address_request(
}
pub fn addr_request0(
context: &Context,
context: &ChannelContext,
current_device: &AtomicCell<CurrentDeviceInfo>,
server_cipher: &Cipher,
) {
@@ -51,7 +51,7 @@ pub fn addr_request0(
let gateway_ip = current_dev.virtual_gateway;
let src_ip = current_dev.virtual_ip;
let mut packet = NetPacket::new_encrypt([0; 12 + ENCRYPTION_RESERVED]).unwrap();
packet.set_version(Version::V1);
packet.set_default_version();
packet.set_gateway_flag(true);
packet.set_protocol(Protocol::Control);
packet.set_transport_protocol(control_packet::Protocol::AddrRequest.into());
+8 -8
View File
@@ -7,18 +7,18 @@ use crossbeam_utils::atomic::AtomicCell;
use parking_lot::Mutex;
use rand::prelude::SliceRandom;
use crate::channel::context::Context;
use crate::channel::context::ChannelContext;
use crate::cipher::Cipher;
use crate::handle::{CurrentDeviceInfo, PeerDeviceInfo};
use crate::protocol::body::ENCRYPTION_RESERVED;
use crate::protocol::control_packet::PingPacket;
use crate::protocol::{control_packet, NetPacket, Protocol, Version};
use crate::protocol::{control_packet, NetPacket, Protocol};
use crate::util::Scheduler;
/// 定时发送心跳包
pub fn heartbeat(
scheduler: &Scheduler,
context: Context,
context: ChannelContext,
current_device_info: Arc<AtomicCell<CurrentDeviceInfo>>,
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
client_cipher: Cipher,
@@ -48,7 +48,7 @@ pub fn heartbeat(
}
fn heartbeat0(
context: &Context,
context: &ChannelContext,
current_device: &CurrentDeviceInfo,
device_list: &Mutex<(u16, Vec<PeerDeviceInfo>)>,
client_cipher: &Cipher,
@@ -125,7 +125,7 @@ fn heartbeat0(
/// 客户端中继路径探测,延迟启动
pub fn client_relay(
scheduler: &Scheduler,
context: Context,
context: ChannelContext,
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
client_cipher: Cipher,
@@ -141,7 +141,7 @@ pub fn client_relay(
/// 客户端中继路径探测,每30秒探测一次
fn client_relay_(
scheduler: &Scheduler,
context: Context,
context: ChannelContext,
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
client_cipher: Cipher,
@@ -163,7 +163,7 @@ fn client_relay_(
}
fn client_relay0(
context: &Context,
context: &ChannelContext,
current_device: &CurrentDeviceInfo,
device_list: &Mutex<(u16, Vec<PeerDeviceInfo>)>,
client_cipher: &Cipher,
@@ -213,7 +213,7 @@ fn heartbeat_packet(
dest: Ipv4Addr,
) -> io::Result<NetPacket<[u8; 12 + 4 + ENCRYPTION_RESERVED]>> {
let mut net_packet = NetPacket::new_encrypt([0u8; 12 + 4 + ENCRYPTION_RESERVED])?;
net_packet.set_version(Version::V1);
net_packet.set_default_version();
net_packet.set_protocol(Protocol::Control);
net_packet.set_transport_protocol(control_packet::Protocol::Ping.into());
net_packet.first_set_ttl(5);
+43 -25
View File
@@ -1,24 +1,24 @@
use std::io;
use std::net::{SocketAddr, ToSocketAddrs};
use std::net::SocketAddr;
use std::sync::Arc;
use std::time::Duration;
use crossbeam_utils::atomic::AtomicCell;
use mio::net::TcpStream;
use crate::channel::context::Context;
use crate::channel::context::ChannelContext;
use crate::channel::idle::{Idle, IdleType};
use crate::channel::sender::AcceptSocketSender;
use crate::handle::callback::{ConnectInfo, ErrorType};
use crate::handle::handshaker::Handshake;
use crate::handle::{handshaker, BaseConfigInfo, ConnectStatus, CurrentDeviceInfo};
use crate::util::Scheduler;
use crate::handle::{BaseConfigInfo, ConnectStatus, CurrentDeviceInfo};
use crate::util::{address_choose, dns_query_all, Scheduler};
use crate::{ErrorInfo, VntCallback};
pub fn idle_route<Call: VntCallback>(
scheduler: &Scheduler,
idle: Idle,
context: Context,
context: ChannelContext,
current_device_info: Arc<AtomicCell<CurrentDeviceInfo>>,
call: Call,
) {
@@ -33,7 +33,7 @@ pub fn idle_route<Call: VntCallback>(
pub fn idle_gateway<Call: VntCallback>(
scheduler: &Scheduler,
context: Context,
context: ChannelContext,
current_device_info: Arc<AtomicCell<CurrentDeviceInfo>>,
config: BaseConfigInfo,
tcp_socket_sender: AcceptSocketSender<(TcpStream, SocketAddr, Option<Vec<u8>>)>,
@@ -68,7 +68,7 @@ pub fn idle_gateway<Call: VntCallback>(
}
fn idle_gateway0<Call: VntCallback>(
context: &Context,
context: &ChannelContext,
current_device: &AtomicCell<CurrentDeviceInfo>,
config: &BaseConfigInfo,
tcp_socket_sender: &AcceptSocketSender<(TcpStream, SocketAddr, Option<Vec<u8>>)>,
@@ -95,7 +95,7 @@ fn idle_gateway0<Call: VntCallback>(
fn idle_route0<Call: VntCallback>(
idle: &Idle,
context: &Context,
context: &ChannelContext,
current_device: &AtomicCell<CurrentDeviceInfo>,
call: &Call,
) -> Duration {
@@ -117,7 +117,7 @@ fn idle_route0<Call: VntCallback>(
}
fn check_gateway_channel<Call: VntCallback>(
context: &Context,
context: &ChannelContext,
current_device_info: &AtomicCell<CurrentDeviceInfo>,
config: &BaseConfigInfo,
tcp_socket_sender: &AcceptSocketSender<(TcpStream, SocketAddr, Option<Vec<u8>>)>,
@@ -133,11 +133,11 @@ fn check_gateway_channel<Call: VntCallback>(
//需要重连
call.connect(ConnectInfo::new(*count, current_device.connect_server));
log::info!("发送握手请求,{:?}", config);
if let Err(e) = handshake.send(context, config.client_secret, current_device.connect_server)
if let Err(e) = handshake.send(context, config.server_secret, current_device.connect_server)
{
log::warn!("{:?}", e);
if context.is_main_tcp() {
let request_packet = handshaker::handshake_request_packet(config.client_secret)?;
let request_packet = handshake.handshake_request_packet(config.server_secret)?;
//tcp需要重连
let tcp_stream = std::net::TcpStream::connect_timeout(
&current_device.connect_server,
@@ -162,24 +162,42 @@ pub fn domain_request0(
config: &BaseConfigInfo,
) -> CurrentDeviceInfo {
let mut current_dev = current_device.load();
// 探测服务端地址变化
if let Ok(mut addr) = config.server_addr.to_socket_addrs() {
if let Some(addr) = addr.next() {
if addr != current_dev.connect_server {
let mut tmp = current_dev.clone();
tmp.connect_server = addr;
let rs = current_device.compare_exchange(current_dev, tmp);
log::info!(
"服务端地址变化,旧地址:{},新地址:{},替换结果:{}",
current_dev.connect_server,
addr,
rs.is_ok()
);
if rs.is_ok() {
current_dev.connect_server = addr;
match dns_query_all(&config.server_addr, config.name_servers.clone()) {
Ok(addrs) => {
log::info!(
"domain {} dns {:?} addr {:?}",
config.server_addr,
config.name_servers,
addrs
);
match address_choose(addrs) {
Ok(addr) => {
if addr != current_dev.connect_server {
let mut tmp = current_dev.clone();
tmp.connect_server = addr;
let rs = current_device.compare_exchange(current_dev, tmp);
log::info!(
"服务端地址变化,旧地址:{},新地址:{},替换结果:{}",
current_dev.connect_server,
addr,
rs.is_ok()
);
if rs.is_ok() {
current_dev.connect_server = addr;
}
}
}
Err(e) => {
log::error!("域名地址选择失败:{:?},domain={}", e, config.server_addr);
}
}
}
Err(e) => {
log::error!("域名解析失败:{:?},domain={}", e, config.server_addr);
}
}
current_dev
}
+7 -7
View File
@@ -10,14 +10,14 @@ use parking_lot::Mutex;
use protobuf::Message;
use rand::prelude::SliceRandom;
use crate::channel::context::Context;
use crate::channel::context::ChannelContext;
use crate::channel::punch::{NatInfo, NatType, Punch};
use crate::cipher::Cipher;
use crate::handle::{CurrentDeviceInfo, PeerDeviceInfo};
use crate::nat::NatTest;
use crate::proto::message::{PunchInfo, PunchNatType};
use crate::protocol::body::ENCRYPTION_RESERVED;
use crate::protocol::{control_packet, other_turn_packet, NetPacket, Protocol, Version, MAX_TTL};
use crate::protocol::{control_packet, other_turn_packet, NetPacket, Protocol, MAX_TTL};
use crate::util::Scheduler;
#[derive(Clone)]
@@ -86,7 +86,7 @@ pub fn punch_channel() -> (PunchSender, PunchReceiver) {
pub fn punch(
scheduler: &Scheduler,
context: Context,
context: ChannelContext,
nat_test: NatTest,
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
@@ -135,7 +135,7 @@ fn punch_start(
) {
while let Ok((peer_ip, nat_info)) = receiver.recv() {
let mut packet = NetPacket::new_encrypt([0u8; 12 + ENCRYPTION_RESERVED]).unwrap();
packet.set_version(Version::V1);
packet.set_default_version();
packet.first_set_ttl(1);
packet.set_protocol(Protocol::Control);
packet.set_transport_protocol(control_packet::Protocol::PunchRequest.into());
@@ -166,7 +166,7 @@ fn punch_start(
/// 定时发起打洞请求
fn punch_request(
scheduler: &Scheduler,
context: Context,
context: ChannelContext,
nat_test: NatTest,
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
@@ -214,7 +214,7 @@ fn punch_request(
/// 随机对需要打洞的客户端发起打洞请求
fn punch0(
context: &Context,
context: &ChannelContext,
nat_test: &NatTest,
device_list: &Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
current_device: CurrentDeviceInfo,
@@ -322,7 +322,7 @@ fn punch_packet(
.write_to_bytes()
.map_err(|e| io::Error::new(io::ErrorKind::Other, format!("punch_packet {:?}", e)))?;
let mut net_packet = NetPacket::new_encrypt(vec![0u8; 12 + bytes.len() + ENCRYPTION_RESERVED])?;
net_packet.set_version(Version::V1);
net_packet.set_default_version();
net_packet.set_protocol(Protocol::OtherTurn);
net_packet.set_transport_protocol(other_turn_packet::Protocol::Punch.into());
net_packet.first_set_ttl(MAX_TTL);
+3 -3
View File
@@ -1,7 +1,7 @@
use std::thread;
use std::time::Duration;
use crate::channel::context::Context;
use crate::channel::context::ChannelContext;
use crate::channel::sender::AcceptSocketSender;
use crate::nat;
use crate::nat::NatTest;
@@ -10,7 +10,7 @@ use crate::util::Scheduler;
/// 10分钟探测一次nat
pub fn retrieve_nat_type(
scheduler: &Scheduler,
context: Context,
context: ChannelContext,
nat_test: NatTest,
udp_socket_sender: AcceptSocketSender<Option<Vec<mio::net::UdpSocket>>>,
) {
@@ -21,7 +21,7 @@ pub fn retrieve_nat_type(
}
fn retrieve_nat_type0(
context: Context,
context: ChannelContext,
nat_test: NatTest,
udp_socket_sender: AcceptSocketSender<Option<Vec<mio::net::UdpSocket>>>,
) {
+6 -6
View File
@@ -1,8 +1,8 @@
use crate::channel::context::Context;
use crate::channel::context::ChannelContext;
use crate::handle::CurrentDeviceInfo;
use crate::proto::message::{ClientStatusInfo, PunchNatType, RouteItem};
use crate::protocol::body::ENCRYPTION_RESERVED;
use crate::protocol::{service_packet, NetPacket, Protocol, Version, HEAD_LEN, MAX_TTL};
use crate::protocol::{service_packet, NetPacket, Protocol, HEAD_LEN, MAX_TTL};
use crate::util::{Scheduler, WatchSingleU64Adder, WatchU64Adder};
use crossbeam_utils::atomic::AtomicCell;
use protobuf::Message;
@@ -13,7 +13,7 @@ use std::time::Duration;
/// 上报状态给服务器
pub fn up_status(
scheduler: &Scheduler,
context: Context,
context: ChannelContext,
current_device_info: Arc<AtomicCell<CurrentDeviceInfo>>,
down_count_watcher: WatchU64Adder,
up_count_watcher: WatchSingleU64Adder,
@@ -31,7 +31,7 @@ pub fn up_status(
fn up_status0(
scheduler: &Scheduler,
context: Context,
context: ChannelContext,
current_device_info: Arc<AtomicCell<CurrentDeviceInfo>>,
down_count_watcher: WatchU64Adder,
up_count_watcher: WatchSingleU64Adder,
@@ -59,7 +59,7 @@ fn up_status0(
}
fn send_up_status_packet(
context: &Context,
context: &ChannelContext,
current_device_info: &AtomicCell<CurrentDeviceInfo>,
down_count_watcher: &WatchU64Adder,
up_count_watcher: &WatchSingleU64Adder,
@@ -91,7 +91,7 @@ fn send_up_status_packet(
.map_err(|e| io::Error::new(io::ErrorKind::Other, format!("up_status_packet {:?}", e)))?;
let mut net_packet =
NetPacket::new_encrypt(vec![0; HEAD_LEN + buf.len() + ENCRYPTION_RESERVED])?;
net_packet.set_version(Version::V1);
net_packet.set_default_version();
net_packet.set_gateway_flag(true);
net_packet.set_protocol(Protocol::Service);
net_packet.set_transport_protocol_into(service_packet::Protocol::ClientStatusInfo);
+18 -4
View File
@@ -32,15 +32,23 @@ pub struct PeerDeviceInfo {
pub name: String,
pub status: PeerDeviceStatus,
pub client_secret: bool,
pub client_secret_hash: Vec<u8>,
}
impl PeerDeviceInfo {
pub fn new(virtual_ip: Ipv4Addr, name: String, status: u8, client_secret: bool) -> Self {
pub fn new(
virtual_ip: Ipv4Addr,
name: String,
status: u8,
client_secret: bool,
client_secret_hash: Vec<u8>,
) -> Self {
Self {
virtual_ip,
name,
status: PeerDeviceStatus::from(status),
client_secret,
client_secret_hash,
}
}
}
@@ -50,9 +58,11 @@ pub struct BaseConfigInfo {
pub name: String,
pub token: String,
pub ip: Option<Ipv4Addr>,
pub client_secret: bool,
pub client_secret_hash: Option<[u8; 16]>,
pub server_secret: bool,
pub device_id: String,
pub server_addr: String,
pub name_servers: Vec<String>,
}
impl BaseConfigInfo {
@@ -60,17 +70,21 @@ impl BaseConfigInfo {
name: String,
token: String,
ip: Option<Ipv4Addr>,
client_secret: bool,
client_secret_hash: Option<[u8; 16]>,
server_secret: bool,
device_id: String,
server_addr: String,
name_servers: Vec<String>,
) -> Self {
Self {
name,
token,
ip,
client_secret,
client_secret_hash,
server_secret,
device_id,
server_addr,
name_servers,
}
}
}
+54 -15
View File
@@ -1,18 +1,15 @@
use parking_lot::RwLock;
use protobuf::Message;
use std::collections::HashMap;
use std::io;
use std::net::{Ipv4Addr, Ipv6Addr};
use std::sync::Arc;
use parking_lot::RwLock;
use protobuf::Message;
use packet::icmp::{icmp, Kind};
use packet::ip::ipv4;
use packet::ip::ipv4::packet::IpV4Packet;
use tun::device::IFace;
use tun::Device;
use crate::channel::context::Context;
use crate::channel::context::ChannelContext;
use crate::channel::punch::NatInfo;
use crate::channel::{Route, RouteKey};
use crate::cipher::Cipher;
@@ -27,13 +24,16 @@ use crate::proto::message::{PunchInfo, PunchNatType};
use crate::protocol::body::ENCRYPTION_RESERVED;
use crate::protocol::control_packet::ControlPacket;
use crate::protocol::{
control_packet, ip_turn_packet, other_turn_packet, NetPacket, Protocol, Version, MAX_TTL,
control_packet, ip_turn_packet, other_turn_packet, NetPacket, Protocol, MAX_TTL,
};
use crate::tun_tap_device::tun_create_helper::DeviceAdapter;
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
use tun::device::IFace;
/// 处理来源于客户端的包
#[derive(Clone)]
pub struct ClientPacketHandler {
device: Arc<Device>,
device: DeviceAdapter,
client_cipher: Cipher,
punch_sender: PunchSender,
peer_nat_info_map: Arc<RwLock<HashMap<Ipv4Addr, NatInfo>>>,
@@ -45,7 +45,7 @@ pub struct ClientPacketHandler {
impl ClientPacketHandler {
pub fn new(
device: Arc<Device>,
device: DeviceAdapter,
client_cipher: Cipher,
punch_sender: PunchSender,
peer_nat_info_map: Arc<RwLock<HashMap<Ipv4Addr, NatInfo>>>,
@@ -71,7 +71,7 @@ impl PacketHandler for ClientPacketHandler {
&self,
mut net_packet: NetPacket<&mut [u8]>,
route_key: RouteKey,
context: &Context,
context: &ChannelContext,
current_device: &CurrentDeviceInfo,
) -> io::Result<()> {
self.client_cipher.decrypt_ipv4(&mut net_packet)?;
@@ -100,7 +100,7 @@ impl ClientPacketHandler {
fn ip_turn(
&self,
mut net_packet: NetPacket<&mut [u8]>,
context: &Context,
context: &ChannelContext,
current_device: &CurrentDeviceInfo,
route_key: RouteKey,
) -> io::Result<()> {
@@ -143,6 +143,31 @@ impl ClientPacketHandler {
//拦截不符合的目标
return Ok(());
}
match ipv4.protocol() {
ipv4::protocol::Protocol::Tcp => {
let payload = ipv4.payload();
if payload.len() < 20 {
return Ok(());
}
let destination_port =
u16::from_be_bytes(payload[2..4].try_into().unwrap());
if self.nat_test.is_local_tcp(real_dest, destination_port) {
return Ok(());
}
}
ipv4::protocol::Protocol::Udp => {
let payload = ipv4.payload();
if payload.len() < 8 {
return Ok(());
}
let destination_port =
u16::from_be_bytes(payload[2..4].try_into().unwrap());
if self.nat_test.is_local_udp(real_dest, destination_port) {
return Ok(());
}
}
_ => {}
}
#[cfg(feature = "ip_proxy")]
if let Some(ip_proxy_map) = &self.ip_proxy_map {
if ip_proxy_map.recv_handle(&mut ipv4, source, destination)? {
@@ -161,7 +186,7 @@ impl ClientPacketHandler {
}
fn control(
&self,
context: &Context,
context: &ChannelContext,
current_device: &CurrentDeviceInfo,
mut net_packet: NetPacket<&mut [u8]>,
route_key: RouteKey,
@@ -193,6 +218,14 @@ impl ClientPacketHandler {
if context.use_channel_type().is_only_relay() {
return Ok(());
}
//忽略掉来源于自己的包
if self
.nat_test
.is_local_address(route_key.is_tcp(), route_key.addr)
{
return Ok(());
}
//回应
net_packet.set_transport_protocol(control_packet::Protocol::PunchResponse.into());
net_packet.set_source(current_device.virtual_ip);
@@ -208,13 +241,19 @@ impl ClientPacketHandler {
if context.use_channel_type().is_only_relay() {
return Ok(());
}
if self
.nat_test
.is_local_address(route_key.is_tcp(), route_key.addr)
{
return Ok(());
}
let route = Route::from_default_rt(route_key, 1);
context.route_table.add_route_if_absent(source, route);
}
ControlPacket::AddrRequest => match route_key.addr.ip() {
std::net::IpAddr::V4(ipv4) => {
let mut packet = NetPacket::new_encrypt([0; 12 + 6 + ENCRYPTION_RESERVED])?;
packet.set_version(Version::V1);
packet.set_default_version();
packet.set_protocol(Protocol::Control);
packet.set_transport_protocol(control_packet::Protocol::AddrResponse.into());
packet.first_set_ttl(MAX_TTL);
@@ -234,7 +273,7 @@ impl ClientPacketHandler {
}
fn other_turn(
&self,
context: &Context,
context: &ChannelContext,
current_device: &CurrentDeviceInfo,
net_packet: NetPacket<&mut [u8]>,
route_key: RouteKey,
@@ -313,7 +352,7 @@ impl ClientPacketHandler {
})?;
let mut punch_packet =
NetPacket::new_encrypt(vec![0u8; 12 + bytes.len() + ENCRYPTION_RESERVED])?;
punch_packet.set_version(Version::V1);
punch_packet.set_default_version();
punch_packet.set_protocol(Protocol::OtherTurn);
punch_packet.set_transport_protocol(other_turn_packet::Protocol::Punch.into());
punch_packet.first_set_ttl(MAX_TTL);
+8 -8
View File
@@ -6,9 +6,7 @@ use std::{io, thread};
use crossbeam_utils::atomic::AtomicCell;
use parking_lot::{Mutex, RwLock};
use tun::Device;
use crate::channel::context::Context;
use crate::channel::context::ChannelContext;
use crate::channel::handler::RecvChannelHandler;
use crate::channel::punch::NatInfo;
use crate::channel::RouteKey;
@@ -27,6 +25,7 @@ use crate::handle::{BaseConfigInfo, CurrentDeviceInfo, PeerDeviceInfo, SELF_IP};
use crate::ip_proxy::IpProxyMap;
use crate::nat::NatTest;
use crate::protocol::NetPacket;
use crate::tun_tap_device::tun_create_helper::DeviceAdapter;
use crate::util::U64Adder;
mod client;
@@ -43,7 +42,7 @@ pub struct RecvDataHandler<Call> {
}
impl<Call: VntCallback> RecvChannelHandler for RecvDataHandler<Call> {
fn handle(&mut self, buf: &mut [u8], route_key: RouteKey, context: &Context) {
fn handle(&mut self, buf: &mut [u8], route_key: RouteKey, context: &ChannelContext) {
if let Err(e) = self.handle0(buf, route_key, context) {
log::error!("[{}]-{:?}", thread::current().name().unwrap_or(""), e);
}
@@ -56,7 +55,7 @@ impl<Call: VntCallback> RecvDataHandler<Call> {
server_cipher: Cipher,
client_cipher: Cipher,
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
device: Arc<Device>,
device: DeviceAdapter,
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
config_info: BaseConfigInfo,
nat_test: NatTest,
@@ -79,7 +78,7 @@ impl<Call: VntCallback> RecvDataHandler<Call> {
config_info,
nat_test.clone(),
callback,
external_route,
external_route.clone(),
handshake,
);
let client = ClientPacketHandler::new(
@@ -105,12 +104,13 @@ impl<Call: VntCallback> RecvDataHandler<Call> {
&mut self,
buf: &mut [u8],
route_key: RouteKey,
context: &Context,
context: &ChannelContext,
) -> io::Result<()> {
// 统计流量
self.counter.add(buf.len() as _);
let net_packet = NetPacket::new(buf)?;
if net_packet.ttl() == 0 || net_packet.source_ttl() < net_packet.ttl() {
log::warn!("丢弃过时包:{:?}", net_packet.head());
return Ok(());
}
let current_device = self.current_device.load();
@@ -145,7 +145,7 @@ pub trait PacketHandler {
&self,
net_packet: NetPacket<&mut [u8]>,
route_key: RouteKey,
context: &Context,
context: &ChannelContext,
current_device: &CurrentDeviceInfo,
) -> io::Result<()>;
}
+102 -23
View File
@@ -11,10 +11,8 @@ use protobuf::Message;
use packet::icmp::{icmp, Kind};
use packet::ip::ipv4;
use packet::ip::ipv4::packet::IpV4Packet;
use tun::device::IFace;
use tun::Device;
use crate::channel::context::Context;
use crate::channel::context::ChannelContext;
use crate::channel::{Route, RouteKey};
use crate::cipher::Cipher;
#[cfg(feature = "server_encrypt")]
@@ -29,12 +27,15 @@ use crate::handle::{
registrar, BaseConfigInfo, ConnectStatus, CurrentDeviceInfo, PeerDeviceInfo, GATEWAY_IP,
};
use crate::nat::NatTest;
use crate::proto;
use crate::proto::message::{DeviceList, HandshakeResponse, RegistrationResponse};
use crate::protocol::body::ENCRYPTION_RESERVED;
use crate::protocol::control_packet::ControlPacket;
use crate::protocol::error_packet::InErrorPacket;
use crate::protocol::{ip_turn_packet, service_packet, NetPacket, Protocol, Version, MAX_TTL};
use crate::protocol::{ip_turn_packet, service_packet, NetPacket, Protocol, MAX_TTL};
use crate::tun_tap_device::tun_create_helper::DeviceAdapter;
use crate::{proto, PeerClientInfo};
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
use tun::device::IFace;
/// 处理来源于服务端的包
#[derive(Clone)]
@@ -43,13 +44,14 @@ pub struct ServerPacketHandler<Call> {
rsa_cipher: Arc<Mutex<Option<RsaCipher>>>,
server_cipher: Cipher,
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
device: Arc<Device>,
device: DeviceAdapter,
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
config_info: BaseConfigInfo,
nat_test: NatTest,
callback: Call,
#[cfg(feature = "server_encrypt")]
up_key_time: Arc<AtomicCell<Instant>>,
#[cfg(not(target_os = "android"))]
route_record: Arc<Mutex<Vec<(Ipv4Addr, Ipv4Addr)>>>,
external_route: ExternalRoute,
handshake: Handshake,
@@ -60,7 +62,7 @@ impl<Call> ServerPacketHandler<Call> {
#[cfg(feature = "server_encrypt")] rsa_cipher: Arc<Mutex<Option<RsaCipher>>>,
server_cipher: Cipher,
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
device: Arc<Device>,
device: DeviceAdapter,
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
config_info: BaseConfigInfo,
nat_test: NatTest,
@@ -80,6 +82,7 @@ impl<Call> ServerPacketHandler<Call> {
callback,
#[cfg(feature = "server_encrypt")]
up_key_time: Arc::new(AtomicCell::new(Instant::now() - Duration::from_secs(60))),
#[cfg(not(target_os = "android"))]
route_record: Arc::new(Mutex::default()),
external_route,
handshake,
@@ -92,7 +95,7 @@ impl<Call: VntCallback> PacketHandler for ServerPacketHandler<Call> {
&self,
mut net_packet: NetPacket<&mut [u8]>,
route_key: RouteKey,
context: &Context,
context: &ChannelContext,
current_device: &CurrentDeviceInfo,
) -> io::Result<()> {
context
@@ -136,13 +139,45 @@ impl<Call: VntCallback> PacketHandler for ServerPacketHandler<Call> {
HandshakeResponse::parse_from_bytes(net_packet.payload()).map_err(|e| {
io::Error::new(io::ErrorKind::Other, format!("HandshakeResponse {:?}", e))
})?;
log::info!("握手响应:{:?},{}", route_key, response);
//如果开启了加密,则发送加密握手请求
#[cfg(feature = "server_encrypt")]
if let Some(key) = self.server_cipher.key() {
{
let guard = self.rsa_cipher.lock();
if let Some(rsa_cipher) = guard.as_ref() {
if rsa_cipher.finger() == &response.key_finger {
let packet = handshaker::secret_handshake_request_packet(
rsa_cipher,
self.config_info.token.clone(),
key,
)?;
drop(guard);
context.send_by_key(packet.buffer(), route_key)?;
return Ok(());
}
log::warn!(
"拒绝服务端密钥对变化,原指纹:{:?},新指纹:{:?}addr:{:?}",
rsa_cipher.finger(),
response.key_finger,
route_key
);
return Ok(());
}
drop(guard);
}
let rsa_cipher = RsaCipher::new(&response.public_key)?;
if rsa_cipher.finger() != &response.key_finger {
log::info!(
"服务端密钥和指纹不匹 配拒绝握手,指纹1:{:?},指纹2:{:?}",
rsa_cipher.finger(),
response.key_finger
);
return Ok(());
}
let handshake_info = HandshakeInfo::new(
rsa_cipher.public_key()?.clone(),
rsa_cipher.finger()?,
response.key_finger,
response.version,
);
log::info!("加密握手请求:{:?}", handshake_info);
@@ -158,7 +193,9 @@ impl<Call: VntCallback> PacketHandler for ServerPacketHandler<Call> {
}
return Ok(());
}
if let Ok(rsa_cipher) = RsaCipher::new(&response.public_key) {
self.rsa_cipher.lock().replace(rsa_cipher);
}
let handshake_info = HandshakeInfo::new_no_secret(response.version);
if self.callback.handshake(handshake_info) {
//没有加密,则发送注册请求
@@ -211,7 +248,7 @@ impl<Call: VntCallback> PacketHandler for ServerPacketHandler<Call> {
impl<Call: VntCallback> ServerPacketHandler<Call> {
fn service(
&self,
context: &Context,
context: &ChannelContext,
current_device: &CurrentDeviceInfo,
net_packet: NetPacket<&mut [u8]>,
route_key: RouteKey,
@@ -267,6 +304,31 @@ impl<Call: VntCallback> ServerPacketHandler<Call> {
if old.virtual_ip != Ipv4Addr::UNSPECIFIED {
log::info!("ip发生变化,old:{:?},response={:?}", old, response);
}
#[cfg(target_os = "android")]
{
let device_config = crate::handle::callback::DeviceConfig::new(
virtual_ip,
virtual_netmask,
virtual_gateway,
virtual_network,
self.external_route.to_route(),
);
let device_fd = self.callback.generate_tun(device_config);
if device_fd == 0 {
self.callback.error(ErrorInfo::new_msg(
ErrorType::Unknown,
"device_fd == 0".into(),
));
} else {
let device = Arc::new(tun::Device::new(device_fd as _)?);
if let Err(e) = self.device.start(device) {
self.callback.error(ErrorInfo::new_msg(
ErrorType::Unknown,
format!("{:?}", e),
));
}
}
}
#[cfg(not(target_os = "android"))]
{
if let Err(e) = self.device.set_ip(virtual_ip, virtual_netmask) {
@@ -356,23 +418,40 @@ impl<Call: VntCallback> ServerPacketHandler<Call> {
info.name,
info.device_status as u8,
info.client_secret,
info.client_secret_hash,
)
})
.collect();
let mut dev = self.device_list.lock();
//这里可能会收到旧的消息,但是随着时间推移总会收到新的
dev.0 = epoch;
dev.1 = ip_list;
{
let mut dev = self.device_list.lock();
//这里可能会收到旧的消息,但是随着时间推移总会收到新的
dev.0 = epoch;
dev.1 = ip_list.clone();
}
self.callback.peer_client_list(
ip_list
.into_iter()
.map(|v| PeerClientInfo::new(v.virtual_ip, v.name, v.status, v.client_secret))
.collect(),
);
}
fn register(&self, current_device: &CurrentDeviceInfo, context: &Context) -> io::Result<()> {
fn register(
&self,
current_device: &CurrentDeviceInfo,
context: &ChannelContext,
) -> io::Result<()> {
if current_device.status.online() {
//已连接的不需要注册
log::info!("已连接的不需要注册,{:?}", self.config_info);
return Ok(());
}
let token = self.config_info.token.clone();
let device_id = self.config_info.device_id.clone();
let name = self.config_info.name.clone();
let client_secret = self.config_info.client_secret;
let client_secret = self
.config_info
.client_secret_hash
.as_ref()
.map(|v| v.as_ref());
let mut ip = self.config_info.ip;
if ip.is_none() {
ip = Some(current_device.virtual_ip)
@@ -393,7 +472,7 @@ impl<Call: VntCallback> ServerPacketHandler<Call> {
}
fn error(
&self,
context: &Context,
context: &ChannelContext,
_current_device: &CurrentDeviceInfo,
net_packet: NetPacket<&mut [u8]>,
route_key: RouteKey,
@@ -415,7 +494,7 @@ impl<Call: VntCallback> ServerPacketHandler<Call> {
drop(dev);
}
self.handshake
.send(context, self.config_info.client_secret, route_key.addr)?;
.send(context, self.config_info.server_secret, route_key.addr)?;
// self.register(current_device, context, route_key)?;
}
InErrorPacket::AddressExhausted => {
@@ -443,7 +522,7 @@ impl<Call: VntCallback> ServerPacketHandler<Call> {
}
fn control(
&self,
context: &Context,
context: &ChannelContext,
current_device: &CurrentDeviceInfo,
net_packet: NetPacket<&mut [u8]>,
route_key: RouteKey,
@@ -464,12 +543,12 @@ impl<Call: VntCallback> ServerPacketHandler<Call> {
let mut poll_device = NetPacket::new_encrypt([0; 12 + ENCRYPTION_RESERVED])?;
poll_device.set_source(current_device.virtual_ip);
poll_device.set_destination(GATEWAY_IP);
poll_device.set_version(Version::V1);
poll_device.set_default_version();
poll_device.set_gateway_flag(true);
poll_device.first_set_ttl(MAX_TTL);
poll_device.set_protocol(Protocol::Service);
poll_device
.set_transport_protocol(service_packet::Protocol::PollDeviceList.into());
.set_transport_protocol(service_packet::Protocol::PullDeviceList.into());
self.server_cipher.encrypt_ipv4(&mut poll_device)?;
//发送到默认服务端即可
context.send_default(poll_device.buffer(), current_device.connect_server)?;
+4 -4
View File
@@ -1,4 +1,4 @@
use crate::channel::context::Context;
use crate::channel::context::ChannelContext;
use crate::channel::RouteKey;
use crate::handle::recv_data::PacketHandler;
use crate::handle::CurrentDeviceInfo;
@@ -19,7 +19,7 @@ impl PacketHandler for TurnPacketHandler {
&self,
mut net_packet: NetPacket<&mut [u8]>,
route_key: RouteKey,
context: &Context,
context: &ChannelContext,
_current_device: &CurrentDeviceInfo,
) -> std::io::Result<()> {
// ttl减一
@@ -33,12 +33,12 @@ impl PacketHandler for TurnPacketHandler {
return Ok(());
}
if route.metric <= ttl {
context.send_by_key(net_packet.buffer(), route.route_key())?;
return context.send_by_key(net_packet.buffer(), route.route_key());
}
}
//其他没有路由的不转发
}
log::info!("没有路由 {:?},{:?}", route_key, net_packet.head());
Ok(())
}
}
+9 -4
View File
@@ -7,7 +7,7 @@ use crate::cipher::Cipher;
use crate::handle::{GATEWAY_IP, SELF_IP};
use crate::proto::message::RegistrationRequest;
use crate::protocol::body::ENCRYPTION_RESERVED;
use crate::protocol::{service_packet, NetPacket, Protocol, Version, MAX_TTL};
use crate::protocol::{service_packet, NetPacket, Protocol, MAX_TTL};
/// 注册数据
pub fn registration_request_packet(
@@ -18,7 +18,7 @@ pub fn registration_request_packet(
ip: Option<Ipv4Addr>,
is_fast: bool,
allow_ip_change: bool,
client_secret: bool,
client_secret_hash: Option<&[u8]>,
) -> io::Result<NetPacket<Vec<u8>>> {
let mut request = RegistrationRequest::new();
request.token = token;
@@ -30,7 +30,12 @@ pub fn registration_request_packet(
request.allow_ip_change = allow_ip_change;
request.is_fast = is_fast;
request.version = crate::VNT_VERSION.to_string();
request.client_secret = client_secret;
if let Some(client_secret_hash) = client_secret_hash {
request.client_secret = true;
request
.client_secret_hash
.extend_from_slice(client_secret_hash);
}
let bytes = request.write_to_bytes().map_err(|e| {
io::Error::new(io::ErrorKind::Other, format!("RegistrationRequest {:?}", e))
})?;
@@ -38,7 +43,7 @@ pub fn registration_request_packet(
let mut net_packet = NetPacket::new_encrypt(buf)?;
net_packet.set_destination(GATEWAY_IP);
net_packet.set_source(SELF_IP);
net_packet.set_version(Version::V1);
net_packet.set_default_version();
net_packet.set_gateway_flag(true);
net_packet.set_protocol(Protocol::Service);
net_packet.set_transport_protocol(service_packet::Protocol::RegistrationRequest.into());
+6 -6
View File
@@ -6,7 +6,7 @@ use parking_lot::Mutex;
use packet::ip::ipv4::packet::IpV4Packet;
use packet::ip::ipv4::protocol::Protocol;
use crate::channel::context::Context;
use crate::channel::context::ChannelContext;
use crate::cipher::Cipher;
use crate::external_route::ExternalRoute;
use crate::handle::{check_dest, CurrentDeviceInfo, PeerDeviceInfo};
@@ -15,14 +15,14 @@ use crate::ip_proxy::{IpProxyMap, ProxyHandler};
use crate::protocol;
use crate::protocol::body::ENCRYPTION_RESERVED;
use crate::protocol::ip_turn_packet::BroadcastPacket;
use crate::protocol::{ip_turn_packet, NetPacket, Version, MAX_TTL};
use crate::protocol::{ip_turn_packet, NetPacket, MAX_TTL};
mod channel_group;
pub mod tun_handler;
fn broadcast(
server_cipher: &Cipher,
sender: &Context,
sender: &ChannelContext,
net_packet: &mut NetPacket<&mut [u8]>,
current_device: &CurrentDeviceInfo,
device_list: &Mutex<(u16, Vec<PeerDeviceInfo>)>,
@@ -87,7 +87,7 @@ fn broadcast(
let buf = vec![0u8; 12 + 1 + p2p_ips.len() * 4 + net_packet.data_len() + ENCRYPTION_RESERVED];
//剩余的发送到服务端,需要告知哪些已发送过
let mut server_packet = NetPacket::new_encrypt(buf)?;
server_packet.set_version(Version::V1);
server_packet.set_default_version();
server_packet.set_gateway_flag(true);
server_packet.first_set_ttl(MAX_TTL);
server_packet.set_source(net_packet.source());
@@ -108,7 +108,7 @@ fn broadcast(
///
#[inline]
pub fn base_handle(
context: &Context,
context: &ChannelContext,
buf: &mut [u8],
data_len: usize, //数据总长度=12+ip包长度
current_device: CurrentDeviceInfo,
@@ -123,7 +123,7 @@ pub fn base_handle(
let src_ip = ipv4_packet.source_ip();
let mut dest_ip = ipv4_packet.destination_ip();
let mut net_packet = NetPacket::new0(data_len, buf)?;
net_packet.set_version(Version::V1);
net_packet.set_default_version();
net_packet.set_protocol(protocol::Protocol::IpTurn);
net_packet.set_transport_protocol(ip_turn_packet::Protocol::Ipv4.into());
net_packet.first_set_ttl(6);
+6 -6
View File
@@ -11,7 +11,7 @@ use packet::ip::ipv4::packet::IpV4Packet;
use tun::device::IFace;
use tun::Device;
use crate::channel::context::Context;
use crate::channel::context::ChannelContext;
use crate::cipher::Cipher;
use crate::external_route::ExternalRoute;
use crate::handle::tun_tap::channel_group::{channel_group, GroupSyncSender};
@@ -38,7 +38,7 @@ fn icmp(device_writer: &Device, mut ipv4_packet: IpV4Packet<&mut [u8]>) -> io::R
/// 接收tun数据,并且转发到udp上
fn handle(
context: &Context,
context: &ChannelContext,
data: &mut [u8],
len: usize,
device_writer: &Device,
@@ -75,7 +75,7 @@ fn handle(
pub fn start(
stop_manager: StopManager,
context: Context,
context: ChannelContext,
device: Arc<Device>,
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
ip_route: ExternalRoute,
@@ -87,14 +87,14 @@ pub fn start(
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
) -> io::Result<()> {
let worker = {
#[cfg(target_os = "macos")]
#[cfg(any(target_os = "macos", target_os = "android"))]
let current_device = current_device.clone();
let device = device.clone();
stop_manager.add_listener("tun_device".into(), move || {
if let Err(e) = device.shutdown() {
log::warn!("{:?}", e);
}
#[cfg(target_os = "macos")]
#[cfg(any(target_os = "macos", target_os = "android"))]
{
let ip = current_device.load().virtual_ip;
if let Ok(udp) = std::net::UdpSocket::bind("0.0.0.0:0") {
@@ -179,7 +179,7 @@ pub fn start(
fn start_simple(
stop_manager: StopManager,
context: &Context,
context: &ChannelContext,
device: Arc<Device>,
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
ip_route: ExternalRoute,
+38 -12
View File
@@ -12,12 +12,12 @@ use packet::icmp::icmp;
use packet::icmp::icmp::HeaderOther;
use packet::ip::ipv4::packet::IpV4Packet;
use crate::channel::context::Context;
use crate::channel::context::ChannelContext;
use crate::cipher::Cipher;
use crate::handle::CurrentDeviceInfo;
use crate::ip_proxy::ProxyHandler;
use crate::protocol;
use crate::protocol::{NetPacket, Version, MAX_TTL};
use crate::protocol::{NetPacket, MAX_TTL};
use crate::util::StopManager;
#[derive(Clone)]
pub struct IcmpProxy {
@@ -28,16 +28,23 @@ pub struct IcmpProxy {
impl IcmpProxy {
pub fn new(
context: Context,
context: ChannelContext,
stop_manager: StopManager,
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
client_cipher: Cipher,
) -> io::Result<Self> {
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
let icmp_socket = socket2::Socket::new(
socket2::Domain::IPV4,
socket2::Type::RAW,
Some(socket2::Protocol::ICMPV4),
)?;
#[cfg(target_os = "android")]
let icmp_socket = socket2::Socket::new(
socket2::Domain::IPV4,
socket2::Type::DGRAM,
Some(socket2::Protocol::ICMPV4),
)?;
let addr: SocketAddrV4 = SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, 0);
icmp_socket.bind(&socket2::SockAddr::from(addr))?;
icmp_socket.set_nonblocking(true)?;
@@ -79,7 +86,7 @@ fn icmp_proxy(
mut icmp_socket: UdpSocket,
// 对端-> 真实来源
nat_map: Arc<Mutex<HashMap<(Ipv4Addr, u16, u16), Ipv4Addr>>>,
context: Context,
context: ChannelContext,
stop_manager: StopManager,
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
client_cipher: Cipher,
@@ -123,12 +130,16 @@ fn readable_handle(
icmp_socket: &UdpSocket,
buf: &mut [u8],
nat_map: &Mutex<HashMap<(Ipv4Addr, u16, u16), Ipv4Addr>>,
context: &Context,
context: &ChannelContext,
current_device: &AtomicCell<CurrentDeviceInfo>,
client_cipher: &Cipher,
) {
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
let start = 12;
#[cfg(target_os = "android")]
let start = 12 + 20;
loop {
let (len, addr) = match icmp_socket.recv_from(&mut buf[12..]) {
let (len, addr) = match icmp_socket.recv_from(&mut buf[start..]) {
Ok(rs) => rs,
Err(e) => {
if e.kind() == io::ErrorKind::WouldBlock {
@@ -139,9 +150,23 @@ fn readable_handle(
}
};
if let IpAddr::V4(peer_ip) = addr.ip() {
#[cfg(target_os = "android")]
{
let buf = &mut buf[12..];
// ipv4 头部20字节
buf[0] = 0b0100_0110;
//写入总长度
buf[2..4].copy_from_slice(&((20 + len) as u16).to_be_bytes());
let mut ipv4 = IpV4Packet::unchecked(buf);
ipv4.set_flags(2);
ipv4.set_ttl(1);
ipv4.set_protocol(packet::ip::ipv4::protocol::Protocol::Icmp);
ipv4.set_source_ip(peer_ip);
}
recv_handle(
buf,
12 + len,
start + len,
peer_ip,
&nat_map,
&context,
@@ -156,7 +181,7 @@ fn recv_handle(
data_len: usize,
peer_ip: Ipv4Addr,
nat_map: &Mutex<HashMap<(Ipv4Addr, u16, u16), Ipv4Addr>>,
context: &Context,
context: &ChannelContext,
current_device: &AtomicCell<CurrentDeviceInfo>,
client_cipher: &Cipher,
) {
@@ -172,7 +197,7 @@ fn recv_handle(
let virtual_ip = current_device.virtual_ip();
let mut net_packet = NetPacket::new0(data_len, buf).unwrap();
net_packet.set_version(Version::V1);
net_packet.set_default_version();
net_packet.set_protocol(protocol::Protocol::IpTurn);
net_packet.set_transport_protocol(
protocol::ip_turn_packet::Protocol::Ipv4.into(),
@@ -225,12 +250,13 @@ impl ProxyHandler for IcmpProxy {
SocketAddr::from(SocketAddrV4::new(dest_ip, 0)),
)?;
}
_ => {
header_other => {
log::warn!(
"不支持的ip代理Icmp协议:{}->{}->{}",
"不支持的ip代理Icmp协议:{}->{}->{},{:?}",
source,
destination,
dest_ip
dest_ip,
header_other
);
}
}
+2 -2
View File
@@ -7,7 +7,7 @@ use crossbeam_utils::atomic::AtomicCell;
use packet::ip::ipv4;
use packet::ip::ipv4::packet::IpV4Packet;
use crate::channel::context::Context;
use crate::channel::context::ChannelContext;
use crate::cipher::Cipher;
use crate::handle::CurrentDeviceInfo;
use crate::ip_proxy::icmp_proxy::IcmpProxy;
@@ -37,7 +37,7 @@ pub struct IpProxyMap {
}
pub fn init_proxy(
context: Context,
context: ChannelContext,
scheduler: Scheduler,
stop_manager: StopManager,
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
+17 -5
View File
@@ -126,6 +126,12 @@ fn udp_proxy(
//所有事件 50分钟超时
if let Err(e) = poll.poll(&mut events, Some(Duration::from_secs(50 * 60))) {
if e.kind() == io::ErrorKind::TimedOut || e.kind() == io::ErrorKind::WouldBlock {
log::warn!(
"超时清理所有udp映射 {},token_map={},udp_map={}",
e,
token_map.len(),
udp_map.len()
);
token_map.clear();
udp_map.clear();
continue;
@@ -198,6 +204,12 @@ fn check_handle(
for token in remove_list {
if let Some((_, src_addr, _)) = token_map.remove(&token) {
udp_map.remove(&src_addr);
log::warn!(
"超时清理udp映射 {},token_map={},udp_map={}",
src_addr,
token_map.len(),
udp_map.len()
);
}
}
}
@@ -246,11 +258,10 @@ fn server_handle(
log::error!("register失败:{:?},addr={:?}", e, dest_addr);
continue;
}
if dest_udp.send(&buf[..len]).is_ok() {
let dest_udp = Rc::new(dest_udp);
token_map.insert(token, (dest_udp.clone(), src_addr, Instant::now()));
udp_map.insert(src_addr, (dest_udp, Instant::now()));
}
let _ = dest_udp.send(&buf[..len]);
let dest_udp = Rc::new(dest_udp);
token_map.insert(token, (dest_udp.clone(), src_addr, Instant::now()));
udp_map.insert(src_addr, (dest_udp, Instant::now()));
}
Err(e) => {
log::error!("绑定目标地址失败:{:?}", e);
@@ -304,6 +315,7 @@ fn readable_handle(
if len == 0 {
return Err(io::Error::from(io::ErrorKind::UnexpectedEof));
}
let _ = udp.send_to(&buf[..len], (*src_addr).into());
}
*time = Instant::now();
+1 -1
View File
@@ -13,4 +13,4 @@ pub mod protocol;
pub mod tun_tap_device;
pub mod util;
pub use handle::callback::{DeviceInfo, ErrorInfo, HandshakeInfo, RegisterInfo, VntCallback};
pub use handle::callback::*;
+68 -2
View File
@@ -1,6 +1,6 @@
use std::io;
use std::net::UdpSocket;
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
use std::net::{SocketAddr, UdpSocket};
use std::ops::Sub;
use std::sync::Arc;
use std::time::{Duration, Instant};
@@ -22,6 +22,7 @@ pub fn local_ipv4_() -> io::Result<Ipv4Addr> {
IpAddr::V6(_) => Ok(Ipv4Addr::UNSPECIFIED),
}
}
pub fn local_ipv4() -> Option<Ipv4Addr> {
match local_ipv4_() {
Ok(ipv4) => Some(ipv4),
@@ -41,6 +42,7 @@ pub fn local_ipv6_() -> io::Result<Ipv6Addr> {
IpAddr::V6(ip) => Ok(ip),
}
}
pub fn local_ipv6() -> Option<Ipv6Addr> {
match local_ipv6_() {
Ok(ipv6) => Some(ipv6),
@@ -56,6 +58,8 @@ pub struct NatTest {
stun_server: Vec<String>,
info: Arc<Mutex<NatInfo>>,
time: Arc<AtomicCell<Instant>>,
udp_ports: Vec<u16>,
tcp_port: u16,
}
impl From<NatType> for PunchNatType {
@@ -94,7 +98,7 @@ impl NatTest {
0,
local_ipv4,
ipv6,
udp_ports,
udp_ports.clone(),
tcp_port,
NatType::Cone,
);
@@ -105,6 +109,8 @@ impl NatTest {
time: Arc::new(AtomicCell::new(
Instant::now().sub(Duration::from_secs(100)),
)),
udp_ports,
tcp_port,
}
}
pub fn can_update(&self) -> bool {
@@ -116,6 +122,66 @@ impl NatTest {
pub fn nat_info(&self) -> NatInfo {
self.info.lock().clone()
}
pub fn is_local_udp(&self, ipv4: Ipv4Addr, port: u16) -> bool {
for x in &self.udp_ports {
if x == &port {
let guard = self.info.lock();
if let Some(ip) = guard.local_ipv4 {
if ipv4 == ip {
return true;
}
}
break;
}
}
false
}
pub fn is_local_tcp(&self, ipv4: Ipv4Addr, port: u16) -> bool {
if self.tcp_port == port {
let guard = self.info.lock();
if let Some(ip) = guard.local_ipv4 {
if ipv4 == ip {
return true;
}
}
}
false
}
pub fn is_local_address(&self, is_tcp: bool, addr: SocketAddr) -> bool {
let port = addr.port();
let check_ip = || {
let guard = self.info.lock();
match addr.ip() {
IpAddr::V4(ipv4) => {
if let Some(ip) = guard.local_ipv4 {
if ipv4 == ip {
return true;
}
}
}
IpAddr::V6(ipv6) => {
if let Some(ip) = guard.ipv6 {
if ipv6 == ip {
return true;
}
}
}
}
false
};
if is_tcp {
if self.tcp_port == port {
return check_ip();
}
} else {
for x in &self.udp_ports {
if x == &port {
return check_ip();
}
}
}
false
}
pub fn update_addr(&self, index: usize, ip: Ipv4Addr, port: u16) {
let mut guard = self.info.lock();
guard.update_addr(index, ip, port)
+85 -34
View File
@@ -1,24 +1,24 @@
use std::collections::HashSet;
use std::io;
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
use std::time::Duration;
use std::{io, thread};
use crate::channel::punch::NatType;
use std::net::UdpSocket;
use stun_format::Attr;
pub fn stun_test_nat(stun_servers: Vec<String>) -> io::Result<(NatType, Vec<Ipv4Addr>, u16)> {
let mut h = Vec::new();
for x in stun_servers {
let handle = thread::spawn(move || test_nat(x));
h.push(handle);
let mut th = Vec::new();
for _ in 0..2 {
let stun_servers = stun_servers.clone();
let handle = std::thread::spawn(move || stun_test_nat0(stun_servers));
th.push(handle);
}
let mut nat_type = NatType::Cone;
let mut port_range = 0;
let mut hash_set = HashSet::new();
for x in h {
if let Ok(rs) = x.join() {
if let Ok((nat_type_t, ip_list_t, port_range_t)) = rs {
for x in th {
match x.join().unwrap() {
Ok((nat_type_t, ip_list_t, port_range_t)) => {
if nat_type_t == NatType::Symmetric {
nat_type = NatType::Symmetric;
}
@@ -29,56 +29,106 @@ pub fn stun_test_nat(stun_servers: Vec<String>) -> io::Result<(NatType, Vec<Ipv4
port_range = port_range_t;
}
}
Err(e) => {
log::warn!("{:?}", e);
}
}
}
Ok((nat_type, hash_set.into_iter().collect(), port_range))
}
fn test_nat(stun_server: String) -> io::Result<(NatType, Vec<Ipv4Addr>, u16)> {
pub fn stun_test_nat0(stun_servers: Vec<String>) -> io::Result<(NatType, Vec<Ipv4Addr>, u16)> {
let udp = UdpSocket::bind("0.0.0.0:0")?;
udp.set_read_timeout(Some(Duration::from_millis(300)))?;
udp.set_read_timeout(Some(Duration::from_millis(500)))?;
let mut nat_type = NatType::Cone;
let mut port_range = 0;
let mut hash_set = HashSet::new();
let mut pub_addrs = HashSet::new();
for x in &stun_servers {
match test_nat(&udp, x) {
Ok((addr, nat_type_t, ip_list_t, port_range_t)) => {
if nat_type_t == NatType::Symmetric {
nat_type = NatType::Symmetric;
}
for x in ip_list_t {
hash_set.insert(x);
}
if port_range < port_range_t {
port_range = port_range_t;
}
pub_addrs.insert(addr);
}
Err(e) => {
log::warn!("stun {} error {:?} ", x, e);
}
}
}
if pub_addrs.len() > 1 {
nat_type = NatType::Symmetric;
}
Ok((nat_type, hash_set.into_iter().collect(), port_range))
}
fn test_nat(
udp: &UdpSocket,
stun_server: &String,
) -> io::Result<(SocketAddr, NatType, Vec<Ipv4Addr>, u16)> {
udp.connect(stun_server)?;
let mut port_range = 0;
let mut hash_set = HashSet::new();
let mut nat_type = NatType::Cone;
match test_nat_(&udp, true, true) {
Ok((mapped_addr1, changed_addr1)) => {
match mapped_addr1.ip() {
IpAddr::V4(ip) => {
hash_set.insert(ip);
}
IpAddr::V6(_) => {}
}
if udp.connect(changed_addr1).is_ok() {
if let Ok((mapped_addr2, _)) = test_nat_(&udp, false, false) {
match mapped_addr2.ip() {
IpAddr::V4(ip) => {
hash_set.insert(ip);
if mapped_addr1 != mapped_addr2 {
nat_type = NatType::Symmetric;
}
// 随便搞个当id
let tid = stun_server.as_ptr() as u128;
let (mapped_addr1, changed_addr1) = test_nat_(&udp, true, true, tid)?;
match mapped_addr1.ip() {
IpAddr::V4(ip) => {
hash_set.insert(ip);
}
IpAddr::V6(_) => {}
}
if udp.connect(changed_addr1).is_ok() {
match test_nat_(&udp, false, false, tid + 1) {
Ok((mapped_addr2, _)) => {
match mapped_addr2.ip() {
IpAddr::V4(ip) => {
hash_set.insert(ip);
if mapped_addr1 != mapped_addr2 {
nat_type = NatType::Symmetric;
}
IpAddr::V6(_) => {}
}
port_range = mapped_addr2.port().abs_diff(mapped_addr1.port());
IpAddr::V6(_) => {}
}
port_range = mapped_addr2.port().abs_diff(mapped_addr1.port());
}
Err(e) => {
log::warn!("stun {} error {:?} ", stun_server, e);
}
}
Err(_) => {}
}
Ok((nat_type, hash_set.into_iter().collect(), port_range))
log::warn!(
"stun {} mapped_addr {:?} nat_type {:?}",
stun_server,
mapped_addr1,
nat_type
);
Ok((
mapped_addr1,
nat_type,
hash_set.into_iter().collect(),
port_range,
))
}
fn test_nat_(
udp: &UdpSocket,
change_ip: bool,
change_port: bool,
tid: u128,
) -> io::Result<(SocketAddr, SocketAddr)> {
for _ in 0..2 {
let mut buf = [0u8; 28];
let mut msg = stun_format::MsgBuilder::from(buf.as_mut_slice());
msg.typ(stun_format::MsgType::BindingRequest).unwrap();
msg.tid(1).unwrap();
msg.tid(tid).unwrap();
msg.add_attr(Attr::ChangeRequest {
change_ip,
change_port,
@@ -88,7 +138,8 @@ fn test_nat_(
let mut buf = [0; 10240];
let (len, _addr) = match udp.recv_from(&mut buf) {
Ok(rs) => rs,
Err(_) => {
Err(e) => {
log::warn!("stun error {:?}", e);
continue;
}
};
+16 -10
View File
@@ -5,14 +5,20 @@ use std::{fmt, io};
pub enum Protocol {
/// ping请求
/*
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| time | echo |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
0 15 31
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| time | echo |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
Ping,
/// 维持连接,内容同ping
/*
0 15 31
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| time | echo |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
Pong,
/// 打洞请求
PunchRequest,
@@ -85,8 +91,8 @@ pub type PongPacket<B> = PingPacket<B>;
impl<B: AsRef<[u8]>> PingPacket<B> {
pub fn new(buffer: B) -> io::Result<PingPacket<B>> {
let len = buffer.as_ref().len();
if len != 4 {
return Err(io::Error::new(io::ErrorKind::InvalidData, "len != 4"));
if len < 4 {
return Err(io::Error::new(io::ErrorKind::InvalidData, "len < 4"));
}
Ok(PingPacket { buffer })
}
@@ -126,8 +132,8 @@ pub struct AddrPacket<B> {
impl<B: AsRef<[u8]>> AddrPacket<B> {
pub fn new(buffer: B) -> io::Result<AddrPacket<B>> {
let len = buffer.as_ref().len();
if len != 6 {
return Err(io::Error::new(io::ErrorKind::InvalidData, "len != 6"));
if len < 6 {
return Err(io::Error::new(io::ErrorKind::InvalidData, "len < 6"));
}
Ok(AddrPacket { buffer })
}
+6 -5
View File
@@ -27,14 +27,15 @@ pub mod service_packet;
#[derive(Eq, PartialEq, Copy, Clone, Debug)]
pub enum Version {
V1,
V2,
Unknown(u8),
}
impl From<u8> for Version {
fn from(value: u8) -> Self {
match value {
1 => Version::V1,
// 版本从2开始,用于和stun协议的binging响应区分开
2 => Version::V2,
val => Version::Unknown(val),
}
}
@@ -43,7 +44,7 @@ impl From<u8> for Version {
impl Into<u8> for Version {
fn into(self) -> u8 {
match self {
Version::V1 => 1,
Version::V2 => 2,
Version::Unknown(val) => val,
}
}
@@ -207,8 +208,8 @@ impl<B: AsRef<[u8]> + AsMut<[u8]>> NetPacket<B> {
self.buffer.as_mut()[0] = self.buffer.as_ref()[0] & 0xBF
};
}
pub fn set_version(&mut self, version: Version) {
let v: u8 = version.into();
pub fn set_default_version(&mut self) {
let v: u8 = Version::V2.into();
self.buffer.as_mut()[0] = (self.buffer.as_ref()[0] & 0xF0) | (0x0F & v);
}
pub fn set_protocol(&mut self, protocol: Protocol) {
+3 -3
View File
@@ -5,7 +5,7 @@ pub enum Protocol {
/// 注册响应
RegistrationResponse,
/// 拉取设备列表
PollDeviceList,
PullDeviceList,
/// 推送设备列表
PushDeviceList,
/// 和服务端握手
@@ -23,7 +23,7 @@ impl From<u8> for Protocol {
match value {
1 => Self::RegistrationRequest,
2 => Self::RegistrationResponse,
3 => Self::PollDeviceList,
3 => Self::PullDeviceList,
4 => Self::PushDeviceList,
5 => Self::HandshakeRequest,
6 => Self::HandshakeResponse,
@@ -40,7 +40,7 @@ impl Into<u8> for Protocol {
match self {
Self::RegistrationRequest => 1,
Self::RegistrationResponse => 2,
Self::PollDeviceList => 3,
Self::PullDeviceList => 3,
Self::PushDeviceList => 4,
Self::HandshakeRequest => 5,
Self::HandshakeResponse => 6,
+64
View File
@@ -0,0 +1,64 @@
use std::io;
use std::sync::Arc;
use tun::device::IFace;
use tun::Device;
#[cfg(any(target_os = "windows", target_os = "linux"))]
const DEFAULT_TUN_NAME: &str = "vnt-tun";
#[cfg(any(target_os = "windows", target_os = "linux"))]
const DEFAULT_TAP_NAME: &str = "vnt-tap";
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
pub fn create_device(config: &crate::core::Config) -> io::Result<Arc<Device>> {
#[cfg(any(target_os = "windows", target_os = "linux"))]
let default_name: &str = if config.tap {
DEFAULT_TAP_NAME
} else {
DEFAULT_TUN_NAME
};
#[cfg(target_os = "linux")]
let device = {
let device_name = config
.device_name
.clone()
.unwrap_or(default_name.to_string());
if &device_name == default_name {
delete_device(default_name);
}
Arc::new(Device::new(Some(device_name), config.tap)?)
};
#[cfg(target_os = "macos")]
let device = Arc::new(Device::new(config.device_name.clone())?);
#[cfg(target_os = "windows")]
let device = Arc::new(Device::new(
config
.device_name
.clone()
.unwrap_or(default_name.to_string()),
config.tap,
)?);
let mtu = config.mtu.unwrap_or_else(|| {
if config.password.is_none() {
1450
} else {
1410
}
});
device.set_mtu(mtu)?;
Ok(device)
}
#[cfg(target_os = "linux")]
fn delete_device(name: &str) {
// 删除默认网卡,此操作有风险,后续可能去除
use std::process::Command;
let cmd = format!("ip link delete {}", name);
let delete_tun = Command::new("sh")
.arg("-c")
.arg(&cmd)
.output()
.expect("sh exec error!");
if !delete_tun.status.success() {
log::warn!("删除网卡失败:{:?}", delete_tun);
}
}
+5 -69
View File
@@ -1,70 +1,6 @@
use std::io;
use std::sync::Arc;
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
pub use create_device::create_device;
use tun::device::IFace;
use tun::Device;
use crate::core::Config;
#[cfg(any(target_os = "windows", target_os = "linux"))]
const DEFAULT_TUN_NAME: &str = "vnt-tun";
#[cfg(any(target_os = "windows", target_os = "linux"))]
const DEFAULT_TAP_NAME: &str = "vnt-tap";
pub fn create_device(config: &Config) -> io::Result<Arc<Device>> {
#[cfg(any(target_os = "windows", target_os = "linux"))]
let default_name: &str = if config.tap {
DEFAULT_TAP_NAME
} else {
DEFAULT_TUN_NAME
};
#[cfg(target_os = "linux")]
let device = {
let device_name = config
.device_name
.clone()
.unwrap_or(default_name.to_string());
if &device_name == default_name {
delete_device(default_name);
}
Arc::new(Device::new(Some(device_name), config.tap)?)
};
#[cfg(target_os = "macos")]
let device = Arc::new(Device::new(config.device_name.clone())?);
#[cfg(target_os = "windows")]
let device = Arc::new(Device::new(
config
.device_name
.clone()
.unwrap_or(default_name.to_string()),
config.tap,
)?);
#[cfg(target_os = "android")]
let device = Arc::new(Device::new(config.device_fd as _)?);
#[cfg(not(target_os = "android"))]
{
let mtu = config.mtu.unwrap_or_else(|| {
if config.password.is_none() {
1450
} else {
1410
}
});
device.set_mtu(mtu)?;
}
Ok(device)
}
#[cfg(target_os = "linux")]
fn delete_device(name: &str) {
// 删除默认网卡,此操作有风险,后续可能去除
use std::process::Command;
let cmd = format!("ip link delete {}", name);
let delete_tun = Command::new("sh")
.arg("-c")
.arg(&cmd)
.output()
.expect("sh exec error!");
if !delete_tun.status.success() {
log::warn!("删除网卡失败:{:?}", delete_tun);
}
}
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
mod create_device;
pub mod tun_create_helper;
+134
View File
@@ -0,0 +1,134 @@
use std::io;
use std::sync::Arc;
use crossbeam_utils::atomic::AtomicCell;
use parking_lot::Mutex;
use tun::Device;
use crate::channel::context::ChannelContext;
use crate::cipher::Cipher;
use crate::external_route::ExternalRoute;
use crate::handle::{CurrentDeviceInfo, PeerDeviceInfo};
use crate::ip_proxy::IpProxyMap;
use crate::util::{SingleU64Adder, StopManager};
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
#[repr(transparent)]
#[derive(Clone)]
pub struct DeviceAdapter {
tun: Arc<Device>,
}
impl DeviceAdapter {
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
pub fn new(tun: Arc<Device>) -> Self {
Self { tun }
}
#[cfg(target_os = "android")]
pub fn new(tun_device_helper: TunDeviceHelper) -> Self {
Self {
tun: Arc::new(Mutex::new(None)),
tun_device_helper,
}
}
}
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
impl std::ops::Deref for DeviceAdapter {
type Target = Arc<Device>;
fn deref(&self) -> &Self::Target {
&self.tun
}
}
#[cfg(target_os = "android")]
#[derive(Clone)]
pub struct DeviceAdapter {
tun: Arc<Mutex<Option<Arc<Device>>>>,
tun_device_helper: TunDeviceHelper,
}
#[cfg(target_os = "android")]
impl DeviceAdapter {
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
if let Some(device) = self.tun.lock().as_ref() {
use tun::device::IFace;
device.write(buf)
} else {
Err(io::Error::new(io::ErrorKind::Other, "not tun device"))
}
}
pub fn start(&self, device: Arc<Device>) -> io::Result<()> {
self.tun_device_helper.start(device.clone())?;
self.tun.lock().replace(device);
Ok(())
}
}
#[derive(Clone)]
pub struct TunDeviceHelper {
inner: Arc<AtomicCell<Option<TunDeviceHelperInner>>>,
}
struct TunDeviceHelperInner {
stop_manager: StopManager,
context: ChannelContext,
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
ip_route: ExternalRoute,
#[cfg(feature = "ip_proxy")]
ip_proxy_map: Option<IpProxyMap>,
client_cipher: Cipher,
server_cipher: Cipher,
parallel: usize,
up_counter: SingleU64Adder,
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
}
impl TunDeviceHelper {
pub fn new(
stop_manager: StopManager,
context: ChannelContext,
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
ip_route: ExternalRoute,
#[cfg(feature = "ip_proxy")] ip_proxy_map: Option<IpProxyMap>,
client_cipher: Cipher,
server_cipher: Cipher,
parallel: usize,
up_counter: SingleU64Adder,
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
) -> Self {
Self {
inner: Arc::new(AtomicCell::new(Some(TunDeviceHelperInner {
stop_manager,
context,
current_device,
ip_route,
ip_proxy_map,
client_cipher,
server_cipher,
parallel,
up_counter,
device_list,
}))),
}
}
pub fn start(&self, device: Arc<Device>) -> io::Result<()> {
if let Some(inner) = self.inner.take() {
crate::handle::tun_tap::tun_handler::start(
inner.stop_manager,
inner.context,
device,
inner.current_device,
inner.ip_route,
#[cfg(feature = "ip_proxy")]
inner.ip_proxy_map,
inner.client_cipher,
inner.server_cipher,
inner.parallel,
inner.up_counter,
inner.device_list,
)?;
Ok(())
} else {
Err(io::Error::new(io::ErrorKind::Other, "Repeated start"))
}
}
}
+274
View File
@@ -0,0 +1,274 @@
use std::cell::RefCell;
use std::collections::HashMap;
use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, ToSocketAddrs, UdpSocket};
use std::str::FromStr;
use std::time::Duration;
use std::{io, thread};
use anyhow::Context;
use dns_parser::{Builder, Packet, QueryClass, QueryType, RData, ResponseCode};
thread_local! {
static HISTORY: RefCell<HashMap<SocketAddr,usize>> = RefCell::new(HashMap::new());
}
/// 保留一个地址使用记录,使用过的地址后续不再选中,直到地址全使用过
pub fn address_choose(addrs: Vec<SocketAddr>) -> anyhow::Result<SocketAddr> {
HISTORY.with(|history| {
let mut available = Vec::new();
for x in &addrs {
let num = history.borrow().get(x).map_or(0, |v| *v);
if num < 3 {
available.push(*x);
}
}
if available.is_empty() {
available = addrs;
history.borrow_mut().clear();
}
let addr = address_choose0(available)?;
history
.borrow_mut()
.entry(addr)
.and_modify(|v| {
*v += 1;
})
.or_insert(1);
Ok(addr)
})
}
/// 后续实现选择延迟最低的可用地址,需要服务端配合
/// 现在是选择第一个地址,优先ipv6
fn address_choose0(addrs: Vec<SocketAddr>) -> anyhow::Result<SocketAddr> {
let v4: Vec<SocketAddr> = addrs.iter().filter(|v| v.is_ipv4()).map(|v| *v).collect();
let v6: Vec<SocketAddr> = addrs.iter().filter(|v| v.is_ipv6()).map(|v| *v).collect();
let check_addr = |addrs: &Vec<SocketAddr>| -> anyhow::Result<SocketAddr> {
if !addrs.is_empty() {
let udp = if addrs[0].is_ipv6() {
UdpSocket::bind("[::]:0")?
} else {
UdpSocket::bind("0.0.0.0:0")?
};
for addr in addrs {
if udp.connect(addr).is_ok() {
return Ok(*addr);
}
}
}
Err(anyhow::anyhow!("Unable to connect to address {:?}", addrs))
};
if v6.is_empty() {
return check_addr(&v4);
}
if v4.is_empty() {
return check_addr(&v6);
}
match check_addr(&v6) {
Ok(addr) => Ok(addr),
Err(e1) => match check_addr(&v4) {
Ok(addr) => Ok(addr),
Err(e2) => Err(anyhow::anyhow!("{} , {}", e1, e2)),
},
}
}
pub fn dns_query_all(
domain: &str,
mut name_servers: Vec<String>,
) -> anyhow::Result<Vec<SocketAddr>> {
match SocketAddr::from_str(domain) {
Ok(addr) => {
return Ok(vec![addr]);
}
Err(_) => {
let txt_domain = domain
.to_lowercase()
.strip_prefix("txt:")
.map(|v| v.to_string());
if name_servers.is_empty() {
if txt_domain.is_some() {
name_servers.push("223.5.5.5:53".into());
name_servers.push("114.114.114.114:53".into());
} else {
return Ok(domain
.to_socket_addrs()
.with_context(|| format!("DNS query failed {:?}", domain))?
.into_iter()
.collect());
}
}
let mut err: Option<anyhow::Error> = None;
for name_server in name_servers {
if let Some(domain) = txt_domain.as_ref() {
return txt_dns(domain, name_server);
}
let end_index = domain
.rfind(":")
.with_context(|| format!("{:?} not port", domain))?;
let host = &domain[..end_index];
let port = u16::from_str(&domain[end_index + 1..])
.with_context(|| format!("{:?} not port", domain))?;
let th1 = {
let host = host.to_string();
let name_server = name_server.clone();
thread::spawn(move || a_dns(host, name_server))
};
let th2 = {
let host = host.to_string();
let name_server = name_server.clone();
thread::spawn(move || aaaa_dns(host, name_server))
};
let mut addr = Vec::new();
match th1.join().unwrap() {
Ok(rs) => {
for ip in rs {
addr.push(SocketAddr::new(ip.into(), port));
}
}
Err(e) => {
err.replace(anyhow::anyhow!("{}", e));
}
}
match th2.join().unwrap() {
Ok(rs) => {
for ip in rs {
addr.push(SocketAddr::new(ip.into(), port));
}
}
Err(e) => {
if addr.is_empty() {
if let Some(err) = &mut err {
*err = anyhow::anyhow!("{},{}", err, e);
} else {
err.replace(anyhow::anyhow!("{}", e));
}
continue;
}
}
}
if addr.is_empty() {
continue;
}
return Ok(addr);
}
if let Some(e) = err {
Err(e)
} else {
Err(anyhow::anyhow!("DNS query failed {:?}", domain))
}
}
}
}
fn query<'a>(
udp: &UdpSocket,
domain: &str,
name_server: SocketAddr,
record_type: QueryType,
buf: &'a mut [u8],
) -> anyhow::Result<Packet<'a>> {
let mut builder = Builder::new_query(1, true);
builder.add_question(domain, false, record_type, QueryClass::IN);
let packet = builder.build().unwrap();
udp.connect(name_server)
.with_context(|| format!("DNS {:?} error ", name_server))?;
let mut count = 0;
let len = loop {
udp.send(&packet)?;
match udp.recv(buf) {
Ok(len) => {
break len;
}
Err(e) => {
if e.kind() == io::ErrorKind::TimedOut || e.kind() == io::ErrorKind::WouldBlock {
count += 1;
if count < 3 {
continue;
}
}
Err(e).with_context(|| format!("DNS {:?} recv error ", name_server))?
}
};
};
let pkt = Packet::parse(&buf[..len])
.with_context(|| format!("domain {:?} DNS {:?} data error ", domain, name_server))?;
if pkt.header.response_code != ResponseCode::NoError {
return Err(anyhow::anyhow!(
"response_code {} DNS {:?} domain {:?}",
pkt.header.response_code,
name_server,
domain
));
}
if pkt.answers.len() == 0 {
return Err(anyhow::anyhow!(
"No records received DNS {:?} domain {:?}",
name_server,
domain
));
}
Ok(pkt)
}
pub fn txt_dns(domain: &str, name_server: String) -> anyhow::Result<Vec<SocketAddr>> {
let name_server: SocketAddr = name_server.parse()?;
let udp = bind_udp(name_server)?;
let mut buf = [0; 65536];
let message = query(&udp, domain, name_server, QueryType::TXT, &mut buf)?;
let mut rs = Vec::new();
for record in message.answers {
if let RData::TXT(txt) = record.data {
for x in txt.iter() {
let txt = std::str::from_utf8(x).context("record type txt is not string")?;
let addr = SocketAddr::from_str(&txt.to_string())
.context("record type txt is not SocketAddr")?;
rs.push(addr);
}
}
}
Ok(rs)
}
fn bind_udp(name_server: SocketAddr) -> anyhow::Result<UdpSocket> {
let udp = if name_server.is_ipv4() {
UdpSocket::bind("0.0.0.0:0")?
} else {
UdpSocket::bind("[::]:0")?
};
udp.set_read_timeout(Some(Duration::from_millis(800)))?;
Ok(udp)
}
pub fn a_dns(domain: String, name_server: String) -> anyhow::Result<Vec<Ipv4Addr>> {
let name_server: SocketAddr = name_server.parse()?;
let udp = bind_udp(name_server)?;
let mut buf = [0; 65536];
let message = query(&udp, &domain, name_server, QueryType::A, &mut buf)?;
let mut rs = Vec::new();
for record in message.answers {
if let RData::A(a) = record.data {
rs.push(a.0);
}
}
Ok(rs)
}
pub fn aaaa_dns(domain: String, name_server: String) -> anyhow::Result<Vec<Ipv6Addr>> {
let name_server: SocketAddr = name_server.parse()?;
let udp = bind_udp(name_server)?;
let mut buf = [0; 65536];
let message = query(&udp, &domain, name_server, QueryType::AAAA, &mut buf)?;
let mut rs = Vec::new();
for record in message.answers {
if let RData::AAAA(a) = record.data {
rs.push(a.0);
}
}
Ok(rs)
}
+3
View File
@@ -7,3 +7,6 @@ pub use scheduler::Scheduler;
mod counter;
pub use counter::*;
mod dns_query;
pub use dns_query::*;