Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
71da72da34 | ||
|
|
c6ef2031fa | ||
|
|
a82933a7a8 | ||
|
|
76444ef17d | ||
|
|
fde33380be | ||
|
|
eedb6684a5 | ||
|
|
a335a5bcdf | ||
|
|
4a347d853e | ||
|
|
79f55fe7fd | ||
|
|
affe8fb719 | ||
|
|
22eee048d0 | ||
|
|
2b2a550a98 | ||
|
|
14427ce437 | ||
|
|
39c170892e | ||
|
|
b82276e6fa | ||
|
|
154e8ef09a | ||
|
|
97a2f7c306 | ||
|
|
8d39d6045a | ||
|
|
04b60773b9 | ||
|
|
774a80dc46 | ||
|
|
1cba257531 | ||
|
|
16cc2abe7a | ||
|
|
595a49ee3f | ||
|
|
f894f62eb2 | ||
|
|
a98d6a7594 | ||
|
|
9674dfa5dc | ||
|
|
00068cdcfd | ||
|
|
846f128689 | ||
|
|
2225edeb2e | ||
|
|
ef48007922 | ||
|
|
1d5257363c | ||
|
|
0238d1ab7e | ||
|
|
ffbb85dfff | ||
|
|
563aca39aa | ||
|
|
274f4df43a | ||
|
|
1fae7c9979 | ||
|
|
46b37c0753 | ||
|
|
f737f591b6 | ||
|
|
ebf8337ad7 | ||
|
|
e2d8a462a2 | ||
|
|
b09cd690f0 | ||
|
|
76bd79d97a | ||
|
|
c0d8645833 |
+132
-109
@@ -7,155 +7,157 @@ on:
|
|||||||
|
|
||||||
env:
|
env:
|
||||||
CARGO_TERM_COLOR: always
|
CARGO_TERM_COLOR: always
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
defaults:
|
defaults:
|
||||||
run:
|
run:
|
||||||
# necessary for windows
|
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
# test:
|
|
||||||
# runs-on: ubuntu-latest
|
|
||||||
# steps:
|
|
||||||
# - uses: actions/checkout@v2
|
|
||||||
# - name: Init submodules
|
|
||||||
# uses: snickerbockers/submodules-init@v4
|
|
||||||
# - name: Cargo cache
|
|
||||||
# uses: actions/cache@v2
|
|
||||||
# with:
|
|
||||||
# path: |
|
|
||||||
# ~/.cargo/registry
|
|
||||||
# ./target
|
|
||||||
# key: test-cargo-registry
|
|
||||||
# - name: List
|
|
||||||
# run: find ./
|
|
||||||
# - name: Run tests
|
|
||||||
# run: cargo test --verbose
|
|
||||||
|
|
||||||
build:
|
build:
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
# a list of all the targets
|
|
||||||
# 选择使用openssl或者ring,并不是所有平台都支持
|
|
||||||
include:
|
include:
|
||||||
- TARGET: i686-unknown-linux-musl # test in an alpine container on a mac
|
- TARGET: i686-unknown-linux-musl
|
||||||
OS: ubuntu-latest
|
OS: ubuntu-latest
|
||||||
FEATURES: default
|
FEATURES: ring-cipher,openssl-vendored,wss
|
||||||
- TARGET: x86_64-unknown-linux-musl # test in an alpine container on a mac
|
- TARGET: x86_64-unknown-linux-musl
|
||||||
OS: ubuntu-latest
|
OS: ubuntu-latest
|
||||||
FEATURES: ring-cipher,wss
|
FEATURES: ring-cipher,wss
|
||||||
- TARGET: aarch64-unknown-linux-musl # tested on aws t4g.nano in alpine container
|
- TARGET: aarch64-unknown-linux-musl
|
||||||
OS: ubuntu-latest
|
OS: ubuntu-latest
|
||||||
FEATURES: ring-cipher,wss
|
FEATURES: ring-cipher,wss
|
||||||
- TARGET: armv7-unknown-linux-musleabihf # raspberry pi 2-3-4, not tested
|
- TARGET: armv7-unknown-linux-musleabihf
|
||||||
OS: ubuntu-latest
|
OS: ubuntu-latest
|
||||||
FEATURES: ring-cipher,wss
|
FEATURES: ring-cipher,wss
|
||||||
- TARGET: armv7-unknown-linux-musleabi # raspberry pi 2-3-4, not tested
|
- TARGET: armv7-unknown-linux-musleabi
|
||||||
OS: ubuntu-latest
|
OS: ubuntu-latest
|
||||||
FEATURES: ring-cipher,wss
|
FEATURES: ring-cipher,wss
|
||||||
- TARGET: arm-unknown-linux-musleabihf # raspberry pi 0-1, not tested
|
- TARGET: arm-unknown-linux-musleabihf
|
||||||
OS: ubuntu-latest
|
OS: ubuntu-latest
|
||||||
FEATURES: ring-cipher,wss
|
FEATURES: ring-cipher,wss
|
||||||
- TARGET: arm-unknown-linux-musleabi # raspberry pi 0-1, not tested
|
- TARGET: arm-unknown-linux-musleabi
|
||||||
OS: ubuntu-latest
|
OS: ubuntu-latest
|
||||||
FEATURES: ring-cipher,wss
|
FEATURES: ring-cipher,wss
|
||||||
- TARGET: x86_64-apple-darwin # tested on a mac, is not properly signed so there are security warnings
|
- TARGET: x86_64-apple-darwin
|
||||||
OS: macos-latest
|
OS: macos-latest
|
||||||
FEATURES: ring-cipher,wss
|
FEATURES: ring-cipher,wss
|
||||||
- TARGET: aarch64-apple-darwin # tested on a mac, is not properly signed so there are security warnings
|
- TARGET: aarch64-apple-darwin
|
||||||
OS: macos-latest
|
OS: macos-latest
|
||||||
FEATURES: ring-cipher,wss
|
FEATURES: ring-cipher,wss
|
||||||
- TARGET: i686-pc-windows-msvc # tested on a windows machine
|
- TARGET: i686-pc-windows-msvc
|
||||||
OS: windows-2019
|
|
||||||
FEATURES: ring-cipher,wss
|
|
||||||
- TARGET: x86_64-pc-windows-msvc # tested on a windows machine
|
|
||||||
OS: windows-latest
|
OS: windows-latest
|
||||||
FEATURES: ring-cipher,wss
|
FEATURES: ring-cipher,wss
|
||||||
- TARGET: mipsel-unknown-linux-musl # openwrt
|
- TARGET: x86_64-pc-windows-msvc
|
||||||
|
OS: windows-latest
|
||||||
|
FEATURES: ring-cipher,wss
|
||||||
|
- TARGET: mipsel-unknown-linux-musl
|
||||||
OS: ubuntu-latest
|
OS: ubuntu-latest
|
||||||
FEATURES: ring-cipher,wss
|
FEATURES: ring-cipher,wss
|
||||||
- TARGET: mips-unknown-linux-musl # openwrt
|
- TARGET: mips-unknown-linux-musl
|
||||||
OS: ubuntu-latest
|
OS: ubuntu-latest
|
||||||
FEATURES: ring-cipher,wss
|
FEATURES: ring-cipher,wss
|
||||||
# needs: test
|
|
||||||
runs-on: ${{ matrix.OS }}
|
runs-on: ${{ matrix.OS }}
|
||||||
env:
|
env:
|
||||||
NAME: vnt-cli # change with the name of your project
|
NAME: vnt-cli
|
||||||
TARGET: ${{ matrix.TARGET }}
|
TARGET: ${{ matrix.TARGET }}
|
||||||
OS: ${{ matrix.OS }}
|
OS: ${{ matrix.OS }}
|
||||||
FEATURES: ${{ matrix.FEATURES }}
|
FEATURES: ${{ matrix.FEATURES }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Init submodules
|
- name: Init submodules
|
||||||
uses: snickerbockers/submodules-init@v4
|
run: git submodule update --init --recursive --remote && git submodule status
|
||||||
|
|
||||||
- name: Cargo cache
|
- name: Cargo cache
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
~/.cargo/registry
|
~/.cargo/registry
|
||||||
./target
|
./target
|
||||||
key: build-cargo-registry-${{matrix.TARGET}}
|
key: build-cargo-registry-${{matrix.TARGET}}
|
||||||
|
|
||||||
- name: Use strawberry perl
|
- name: Use strawberry perl
|
||||||
if: startsWith(matrix.os, 'windows')
|
if: startsWith(matrix.OS, 'windows')
|
||||||
run: echo OPENSSL_SRC_PERL=C:/Strawberry/perl/bin/perl >> $GITHUB_ENV
|
run: echo OPENSSL_SRC_PERL=C:/Strawberry/perl/bin/perl >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: List
|
- name: List
|
||||||
run: find ./
|
run: find ./
|
||||||
- name: Install and configure dependencies
|
|
||||||
|
- name: Install Rust toolchain
|
||||||
|
uses: actions-rs/toolchain@v1
|
||||||
|
with:
|
||||||
|
toolchain: nightly
|
||||||
|
profile: minimal
|
||||||
|
override: true
|
||||||
|
|
||||||
|
- name: Verify Rust version
|
||||||
run: |
|
run: |
|
||||||
# dependencies are only needed on ubuntu as that's the only place where
|
rustc --version
|
||||||
# we make cross-compilation
|
cargo --version
|
||||||
rustup set auto-self-update disable
|
|
||||||
|
|
||||||
if [[ $OS =~ ^ubuntu.*$ ]]; then
|
- name: Install dependencies on Ubuntu
|
||||||
sudo apt-get update && sudo apt-get install clang llvm libc6-dev-i386 crossbuild-essential-arm64 crossbuild-essential-armhf musl-tools libboost-all-dev libc6-dev -y
|
if: startsWith(matrix.OS, 'ubuntu')
|
||||||
# curl -s musl.cc | grep mipsel
|
run: |
|
||||||
case $TARGET in
|
sudo apt-get update && sudo apt-get install -y clang llvm libc6-dev-i386 \
|
||||||
mipsel-unknown-linux-musl)
|
crossbuild-essential-arm64 crossbuild-essential-armhf musl-tools libboost-all-dev libc6-dev wget tar
|
||||||
MUSL_URI=mipsel-linux-musl-cross
|
|
||||||
;;
|
|
||||||
aarch64-unknown-linux-musl)
|
|
||||||
MUSL_URI=aarch64-linux-musl-cross
|
|
||||||
;;
|
|
||||||
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
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
if [[ $TARGET =~ ^mips.*$ ]]; then
|
# Install musl cross toolchains if needed
|
||||||
# mips平台使用1.71.1版本
|
case $TARGET in
|
||||||
rustup install 1.71.1
|
mipsel-unknown-linux-musl)
|
||||||
rustup default 1.71.1
|
MUSL_URI=mipsel-linux-muslsf-cross
|
||||||
else
|
URL=mipsel-linux-muslsf
|
||||||
rustup install 1.77
|
;;
|
||||||
rustup default 1.77
|
aarch64-unknown-linux-musl)
|
||||||
fi
|
MUSL_URI=aarch64-linux-musl-cross
|
||||||
|
;;
|
||||||
|
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-muslsf-cross
|
||||||
|
URL=mips-linux-muslsf
|
||||||
|
;;
|
||||||
|
i686-unknown-linux-musl)
|
||||||
|
MUSL_URI=i686-linux-musl-cross
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
if [ -n "$MUSL_URI" ]; then
|
if [ -n "$MUSL_URI" ]; then
|
||||||
mkdir -p ./musl_gcc
|
mkdir -p /opt/musl_gcc
|
||||||
wget -c https://musl.cc/$MUSL_URI.tgz -P ./musl_gcc/
|
wget -c https://github.com/rustp2p/musl-cross/releases/download/0.0.1/$MUSL_URI.tgz -P /opt/musl_gcc/
|
||||||
tar zxf ./musl_gcc/$MUSL_URI.tgz -C ./musl_gcc/
|
tar zxf /opt/musl_gcc/$MUSL_URI.tgz -C /opt/musl_gcc/
|
||||||
sudo ln -s $(pwd)/musl_gcc/$MUSL_URI/bin/*gcc /usr/bin/
|
sudo ln -s /opt/musl_gcc/$MUSL_URI/bin/*gcc /usr/bin/
|
||||||
fi
|
|
||||||
else
|
|
||||||
rustup install 1.77
|
|
||||||
rustup default 1.77
|
|
||||||
fi
|
fi
|
||||||
rustup -V
|
|
||||||
|
|
||||||
# some additional configuration for cross-compilation on linux
|
if [[ $TARGET =~ ^mips.*$ ]]; then
|
||||||
|
cd /opt/musl_gcc/${URL}-cross/lib/gcc/${URL}/11.2.1
|
||||||
|
cp libgcc_eh.a libunwind.a
|
||||||
|
rustup toolchain install nightly-x86_64-unknown-linux-gnu
|
||||||
|
rustup component add rust-src --toolchain nightly-x86_64-unknown-linux-gnu
|
||||||
|
RUST_LIB_SRC=$HOME/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/
|
||||||
|
if [[ -f $RUST_LIB_SRC/library/Cargo.lock && ! -f $RUST_LIB_SRC/Cargo.lock ]]; then
|
||||||
|
cp -f $RUST_LIB_SRC/library/Cargo.lock $RUST_LIB_SRC/Cargo.lock
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
rustup -V
|
||||||
|
|
||||||
|
|
||||||
|
- name: Configure cargo for cross-compilation
|
||||||
|
run: |
|
||||||
cat >>~/.cargo/config <<EOF
|
cat >>~/.cargo/config <<EOF
|
||||||
[target.x86_64-unknown-linux-musl]
|
[target.x86_64-unknown-linux-musl]
|
||||||
rustflags = ["-C", "target-feature=+crt-static","-C", "strip=symbols"]
|
rustflags = ["-C", "target-feature=+crt-static","-C", "strip=symbols"]
|
||||||
@@ -175,11 +177,17 @@ jobs:
|
|||||||
linker = "arm-linux-musleabi-gcc"
|
linker = "arm-linux-musleabi-gcc"
|
||||||
rustflags = ["-C", "target-feature=+crt-static","-C", "strip=symbols"]
|
rustflags = ["-C", "target-feature=+crt-static","-C", "strip=symbols"]
|
||||||
[target.mipsel-unknown-linux-musl]
|
[target.mipsel-unknown-linux-musl]
|
||||||
linker = "mipsel-linux-musl-gcc"
|
linker = "mipsel-linux-muslsf-gcc"
|
||||||
rustflags = ["-C", "target-feature=+crt-static","-C", "strip=symbols"]
|
rustflags = ["-C", "target-feature=+crt-static","-C", "strip=symbols","-C", "link-arg=-static",
|
||||||
|
"-C", "relocation-model=static","-C", "link-arg=-no-pie","--cfg", "compiler_builtins_no_debug",
|
||||||
|
"-L", "/opt/musl_gcc/mipsel-linux-muslsf-cross/mipsel-linux-muslsf/lib",
|
||||||
|
"-L", "/opt/musl_gcc/mipsel-linux-muslsf-cross/lib/gcc/mipsel-linux-muslsf/11.2.1"]
|
||||||
[target.mips-unknown-linux-musl]
|
[target.mips-unknown-linux-musl]
|
||||||
linker = "mips-linux-musl-gcc"
|
linker = "mips-linux-muslsf-gcc"
|
||||||
rustflags = ["-C", "target-feature=+crt-static","-C", "strip=symbols"]
|
rustflags = ["-C", "target-feature=+crt-static","-C", "strip=symbols","-C", "link-arg=-static",
|
||||||
|
"-C", "relocation-model=static","-C", "link-arg=-no-pie","--cfg", "compiler_builtins_no_debug",
|
||||||
|
"-L", "/opt/musl_gcc/mips-linux-muslsf-cross/mips-linux-muslsf/lib",
|
||||||
|
"-L", "/opt/musl_gcc/mips-linux-muslsf-cross/lib/gcc/mips-linux-muslsf/11.2.1"]
|
||||||
[target.x86_64-pc-windows-msvc]
|
[target.x86_64-pc-windows-msvc]
|
||||||
rustflags = ["-C", "target-feature=+crt-static","-C", "strip=symbols"]
|
rustflags = ["-C", "target-feature=+crt-static","-C", "strip=symbols"]
|
||||||
[target.i686-pc-windows-msvc]
|
[target.i686-pc-windows-msvc]
|
||||||
@@ -189,20 +197,34 @@ jobs:
|
|||||||
[target.aarch64-apple-darwin]
|
[target.aarch64-apple-darwin]
|
||||||
rustflags = ["-C", "target-feature=+crt-static","-C", "strip=symbols"]
|
rustflags = ["-C", "target-feature=+crt-static","-C", "strip=symbols"]
|
||||||
[target.i686-unknown-linux-musl]
|
[target.i686-unknown-linux-musl]
|
||||||
|
linker = "i686-linux-musl-gcc"
|
||||||
rustflags = ["-C", "target-feature=+crt-static","-C", "strip=symbols"]
|
rustflags = ["-C", "target-feature=+crt-static","-C", "strip=symbols"]
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
- name: Install rust target
|
- name: Install rust target
|
||||||
|
if: ${{ ! endsWith(matrix.TARGET, 'freebsd') && ! startsWith(matrix.TARGET, 'mips') }}
|
||||||
run: rustup target add $TARGET
|
run: rustup target add $TARGET
|
||||||
|
|
||||||
- name: Run build vn-link-cli
|
- name: Run build vn-link-cli
|
||||||
run: cargo build --package vn-link-cli --release --verbose --target $TARGET --features $FEATURES
|
run: |
|
||||||
|
if [[ $TARGET =~ ^mips.*$ ]]; then
|
||||||
|
cargo +nightly build --package vn-link-cli --release --target $TARGET -Z build-std=std,panic_abort --features $FEATURES
|
||||||
|
else
|
||||||
|
cargo build --package vn-link-cli --release --target $TARGET --features $FEATURES
|
||||||
|
fi
|
||||||
|
|
||||||
- name: Run build vnt-cli
|
- name: Run build vnt-cli
|
||||||
run: cargo build --package vnt-cli --release --verbose --target $TARGET --features $FEATURES
|
run: |
|
||||||
|
if [[ $TARGET =~ ^mips.*$ ]]; then
|
||||||
|
cargo +nightly build --package vnt-cli --release --target $TARGET -Z build-std=std,panic_abort --features $FEATURES
|
||||||
|
else
|
||||||
|
cargo build --package vnt-cli --release --target $TARGET --features $FEATURES
|
||||||
|
fi
|
||||||
- name: List target
|
- name: List target
|
||||||
run: find ./target
|
run: find ./target
|
||||||
- name: Compress
|
- name: Compress
|
||||||
run: |
|
run: |
|
||||||
mkdir -p ./artifacts
|
mkdir -p ./artifacts
|
||||||
# windows is the only OS using a different convention for executable file name
|
|
||||||
if [[ $OS =~ ^windows.*$ ]]; then
|
if [[ $OS =~ ^windows.*$ ]]; then
|
||||||
EXEC_VNT_CLI=vnt-cli.exe
|
EXEC_VNT_CLI=vnt-cli.exe
|
||||||
EXEC_VN_LINK_CLI=vn-link-cli.exe
|
EXEC_VN_LINK_CLI=vn-link-cli.exe
|
||||||
@@ -220,30 +242,31 @@ jobs:
|
|||||||
mv ./README ./artifacts/README.txt
|
mv ./README ./artifacts/README.txt
|
||||||
cd ./artifacts
|
cd ./artifacts
|
||||||
tar -czf vnt-$TARGET-$TAG.tar.gz *
|
tar -czf vnt-$TARGET-$TAG.tar.gz *
|
||||||
|
mkdir upload_file
|
||||||
|
mv vnt-$TARGET-$TAG.tar.gz ./upload_file/
|
||||||
|
|
||||||
- name: Archive artifact
|
- name: Archive artifact
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: vnt-cli
|
name: vnt-cli-${{ matrix.TARGET }}
|
||||||
path: |
|
path: ./artifacts/upload_file
|
||||||
./artifacts
|
|
||||||
# deploys to github releases on tag
|
|
||||||
deploy:
|
deploy:
|
||||||
if: startsWith(github.ref, 'refs/tags/')
|
if: startsWith(github.ref, 'refs/tags/')
|
||||||
needs: build
|
needs: build
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Download artifacts
|
- name: Download artifacts
|
||||||
uses: actions/download-artifact@v3
|
uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: vnt-cli
|
|
||||||
path: ./artifacts
|
path: ./artifacts
|
||||||
- name: List
|
- name: List
|
||||||
run: find ./artifacts
|
run: find ./artifacts
|
||||||
- name: Release
|
- name: Release
|
||||||
uses: svenstaro/upload-release-action@v2
|
uses: svenstaro/upload-release-action@v2
|
||||||
with:
|
with:
|
||||||
repo_token: ${{ secrets.YOURTOKEN }}
|
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
file: ./artifacts/*.tar.gz
|
file: ./artifacts/**/*.tar.gz
|
||||||
tag: ${{ github.ref }}
|
tag: ${{ github.ref }}
|
||||||
overwrite: true
|
overwrite: true
|
||||||
file_glob: true
|
file_glob: true
|
||||||
Generated
-2535
@@ -1,2535 +0,0 @@
|
|||||||
# This file is automatically @generated by Cargo.
|
|
||||||
# It is not intended for manual editing.
|
|
||||||
version = 3
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "addr2line"
|
|
||||||
version = "0.21.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb"
|
|
||||||
dependencies = [
|
|
||||||
"gimli",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "adler"
|
|
||||||
version = "1.0.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
|
||||||
|
|
||||||
[[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 = "attohttpc"
|
|
||||||
version = "0.16.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "fdb8867f378f33f78a811a8eb9bf108ad99430d7aad43315dd9319c827ef6247"
|
|
||||||
dependencies = [
|
|
||||||
"http 0.2.12",
|
|
||||||
"log",
|
|
||||||
"url",
|
|
||||||
"wildmatch",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "autocfg"
|
|
||||||
version = "1.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "backtrace"
|
|
||||||
version = "0.3.71"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d"
|
|
||||||
dependencies = [
|
|
||||||
"addr2line",
|
|
||||||
"cc",
|
|
||||||
"cfg-if",
|
|
||||||
"libc",
|
|
||||||
"miniz_oxide",
|
|
||||||
"object",
|
|
||||||
"rustc-demangle",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "base64"
|
|
||||||
version = "0.22.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "base64ct"
|
|
||||||
version = "1.6.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "bindgen"
|
|
||||||
version = "0.69.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags 2.5.0",
|
|
||||||
"cexpr",
|
|
||||||
"clang-sys",
|
|
||||||
"itertools",
|
|
||||||
"lazy_static",
|
|
||||||
"lazycell",
|
|
||||||
"log",
|
|
||||||
"prettyplease",
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"regex",
|
|
||||||
"rustc-hash",
|
|
||||||
"shlex",
|
|
||||||
"syn 2.0.60",
|
|
||||||
"which",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[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.99"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "96c51067fd44124faa7f870b4b1c969379ad32b2ba805aa959430ceaa384f695"
|
|
||||||
dependencies = [
|
|
||||||
"jobserver",
|
|
||||||
"libc",
|
|
||||||
"once_cell",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cexpr"
|
|
||||||
version = "0.6.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
|
|
||||||
dependencies = [
|
|
||||||
"nom",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cfg-if"
|
|
||||||
version = "1.0.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cfg_aliases"
|
|
||||||
version = "0.2.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "chacha20"
|
|
||||||
version = "0.9.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
"cipher",
|
|
||||||
"cpufeatures",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "chacha20poly1305"
|
|
||||||
version = "0.10.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35"
|
|
||||||
dependencies = [
|
|
||||||
"aead",
|
|
||||||
"chacha20",
|
|
||||||
"cipher",
|
|
||||||
"poly1305",
|
|
||||||
"zeroize",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[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.6",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cipher"
|
|
||||||
version = "0.4.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"
|
|
||||||
dependencies = [
|
|
||||||
"crypto-common",
|
|
||||||
"inout",
|
|
||||||
"zeroize",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "clang-sys"
|
|
||||||
version = "1.8.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4"
|
|
||||||
dependencies = [
|
|
||||||
"glob",
|
|
||||||
"libc",
|
|
||||||
"libloading",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "common"
|
|
||||||
version = "1.2.14"
|
|
||||||
dependencies = [
|
|
||||||
"anyhow",
|
|
||||||
"chrono",
|
|
||||||
"console",
|
|
||||||
"gethostname",
|
|
||||||
"getopts",
|
|
||||||
"log",
|
|
||||||
"log4rs",
|
|
||||||
"rand",
|
|
||||||
"serde",
|
|
||||||
"serde_yaml",
|
|
||||||
"sys-locale",
|
|
||||||
"uuid",
|
|
||||||
"vnt",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[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"
|
|
||||||
version = "0.9.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f"
|
|
||||||
dependencies = [
|
|
||||||
"core-foundation-sys",
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[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"
|
|
||||||
version = "0.8.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1137cd7e7fc0fb5d3c5a8678be38ec56e819125d8d7907411fe24ccb943faca8"
|
|
||||||
dependencies = [
|
|
||||||
"crossbeam-channel",
|
|
||||||
"crossbeam-deque",
|
|
||||||
"crossbeam-epoch",
|
|
||||||
"crossbeam-queue",
|
|
||||||
"crossbeam-utils",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "crossbeam-channel"
|
|
||||||
version = "0.5.13"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2"
|
|
||||||
dependencies = [
|
|
||||||
"crossbeam-utils",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "crossbeam-deque"
|
|
||||||
version = "0.8.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d"
|
|
||||||
dependencies = [
|
|
||||||
"crossbeam-epoch",
|
|
||||||
"crossbeam-utils",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[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 = "data-encoding"
|
|
||||||
version = "2.6.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2"
|
|
||||||
|
|
||||||
[[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 = "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 = "form_urlencoded"
|
|
||||||
version = "1.2.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
|
|
||||||
dependencies = [
|
|
||||||
"percent-encoding",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "futures-core"
|
|
||||||
version = "0.3.30"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "futures-macro"
|
|
||||||
version = "0.3.30"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn 2.0.60",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "futures-sink"
|
|
||||||
version = "0.3.30"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "futures-task"
|
|
||||||
version = "0.3.30"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "futures-util"
|
|
||||||
version = "0.3.30"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
|
|
||||||
dependencies = [
|
|
||||||
"futures-core",
|
|
||||||
"futures-macro",
|
|
||||||
"futures-sink",
|
|
||||||
"futures-task",
|
|
||||||
"pin-project-lite",
|
|
||||||
"pin-utils",
|
|
||||||
"slab",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[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 = "gethostname"
|
|
||||||
version = "0.4.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0176e0459c2e4a1fe232f984bca6890e681076abb9934f6cea7c326f3fc47818"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"windows-targets 0.48.5",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[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 = "gimli"
|
|
||||||
version = "0.28.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "glob"
|
|
||||||
version = "0.3.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
|
|
||||||
|
|
||||||
[[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 = "hermit-abi"
|
|
||||||
version = "0.3.9"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
|
|
||||||
|
|
||||||
[[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 = "http"
|
|
||||||
version = "0.2.12"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1"
|
|
||||||
dependencies = [
|
|
||||||
"bytes",
|
|
||||||
"fnv",
|
|
||||||
"itoa",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "http"
|
|
||||||
version = "1.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258"
|
|
||||||
dependencies = [
|
|
||||||
"bytes",
|
|
||||||
"fnv",
|
|
||||||
"itoa",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "httparse"
|
|
||||||
version = "1.9.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9"
|
|
||||||
|
|
||||||
[[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 = "idna"
|
|
||||||
version = "0.5.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6"
|
|
||||||
dependencies = [
|
|
||||||
"unicode-bidi",
|
|
||||||
"unicode-normalization",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "igd"
|
|
||||||
version = "0.12.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "556b5a75cd4adb7c4ea21c64af1c48cefb2ce7d43dc4352c720a1fe47c21f355"
|
|
||||||
dependencies = [
|
|
||||||
"attohttpc",
|
|
||||||
"log",
|
|
||||||
"rand",
|
|
||||||
"url",
|
|
||||||
"xmltree",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[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 = "itertools"
|
|
||||||
version = "0.12.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
|
|
||||||
dependencies = [
|
|
||||||
"either",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "itoa"
|
|
||||||
version = "1.0.11"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "jobserver"
|
|
||||||
version = "0.1.31"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[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 = "lazycell"
|
|
||||||
version = "1.3.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "libc"
|
|
||||||
version = "0.2.155"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
|
|
||||||
|
|
||||||
[[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.6",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[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/vnt-dev/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 = "lwip-rs"
|
|
||||||
version = "0.1.0"
|
|
||||||
source = "git+https://github.com/vnt-dev/lwip-rs#3133f0c3bde55333a27641182ae3550e7acc2a39"
|
|
||||||
dependencies = [
|
|
||||||
"bindgen",
|
|
||||||
"cc",
|
|
||||||
"crossbeam",
|
|
||||||
"lazy_static",
|
|
||||||
"log",
|
|
||||||
"parking_lot",
|
|
||||||
"tokio",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "lz4_flex"
|
|
||||||
version = "0.11.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "75761162ae2b0e580d7e7c390558127e5f01b4194debd6221fd8c207fc80e3f5"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "memchr"
|
|
||||||
version = "2.7.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "minimal-lexical"
|
|
||||||
version = "0.2.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "miniz_oxide"
|
|
||||||
version = "0.7.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7"
|
|
||||||
dependencies = [
|
|
||||||
"adler",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[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 = "network-interface"
|
|
||||||
version = "2.0.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "433419f898328beca4f2c6c73a1b52540658d92b0a99f0269330457e0fd998d5"
|
|
||||||
dependencies = [
|
|
||||||
"cc",
|
|
||||||
"libc",
|
|
||||||
"thiserror",
|
|
||||||
"winapi",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "nom"
|
|
||||||
version = "7.1.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
|
|
||||||
dependencies = [
|
|
||||||
"memchr",
|
|
||||||
"minimal-lexical",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[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 = "num_cpus"
|
|
||||||
version = "1.16.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
|
|
||||||
dependencies = [
|
|
||||||
"hermit-abi",
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "object"
|
|
||||||
version = "0.32.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441"
|
|
||||||
dependencies = [
|
|
||||||
"memchr",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[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-probe"
|
|
||||||
version = "0.1.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
|
|
||||||
|
|
||||||
[[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/vnt-dev/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 = "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 = "percent-encoding"
|
|
||||||
version = "2.3.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pin-project-lite"
|
|
||||||
version = "0.2.14"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pin-utils"
|
|
||||||
version = "0.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
|
||||||
|
|
||||||
[[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 = "poly1305"
|
|
||||||
version = "0.8.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf"
|
|
||||||
dependencies = [
|
|
||||||
"cpufeatures",
|
|
||||||
"opaque-debug",
|
|
||||||
"universal-hash",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[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 = "prettyplease"
|
|
||||||
version = "0.2.20"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"syn 2.0.60",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[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.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b55bad9126f378a853655831eb7363b7b01b81d19f8cb1218861086ca4a1a61e"
|
|
||||||
dependencies = [
|
|
||||||
"once_cell",
|
|
||||||
"protobuf-support",
|
|
||||||
"thiserror",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "protobuf-codegen"
|
|
||||||
version = "3.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0dd418ac3c91caa4032d37cb80ff0d44e2ebe637b2fb243b6234bf89cdac4901"
|
|
||||||
dependencies = [
|
|
||||||
"anyhow",
|
|
||||||
"once_cell",
|
|
||||||
"protobuf",
|
|
||||||
"protobuf-parse",
|
|
||||||
"regex",
|
|
||||||
"tempfile",
|
|
||||||
"thiserror",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "protobuf-parse"
|
|
||||||
version = "3.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9d39b14605eaa1f6a340aec7f320b34064feb26c93aec35d6a9a2272a8ddfa49"
|
|
||||||
dependencies = [
|
|
||||||
"anyhow",
|
|
||||||
"indexmap 1.9.3",
|
|
||||||
"log",
|
|
||||||
"protobuf",
|
|
||||||
"protobuf-support",
|
|
||||||
"tempfile",
|
|
||||||
"thiserror",
|
|
||||||
"which",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "protobuf-support"
|
|
||||||
version = "3.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a5d4d7b8601c814cfb36bcebb79f0e61e45e1e93640cf778837833bbed05c372"
|
|
||||||
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 = "rustc-demangle"
|
|
||||||
version = "0.1.23"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rustc-hash"
|
|
||||||
version = "1.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
|
||||||
|
|
||||||
[[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 = "rustls"
|
|
||||||
version = "0.23.10"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "05cff451f60db80f490f3c182b77c35260baace73209e9cdbbe526bfe3a4d402"
|
|
||||||
dependencies = [
|
|
||||||
"once_cell",
|
|
||||||
"ring",
|
|
||||||
"rustls-pki-types",
|
|
||||||
"rustls-webpki",
|
|
||||||
"subtle",
|
|
||||||
"zeroize",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rustls-native-certs"
|
|
||||||
version = "0.7.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a88d6d420651b496bdd98684116959239430022a115c1240e6c3993be0b15fba"
|
|
||||||
dependencies = [
|
|
||||||
"openssl-probe",
|
|
||||||
"rustls-pemfile",
|
|
||||||
"rustls-pki-types",
|
|
||||||
"schannel",
|
|
||||||
"security-framework",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rustls-pemfile"
|
|
||||||
version = "2.1.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d"
|
|
||||||
dependencies = [
|
|
||||||
"base64",
|
|
||||||
"rustls-pki-types",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rustls-pki-types"
|
|
||||||
version = "1.7.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rustls-webpki"
|
|
||||||
version = "0.102.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ff448f7e92e913c4b7d4c6d8e4540a1724b319b4152b8aef6d4cf8339712b33e"
|
|
||||||
dependencies = [
|
|
||||||
"ring",
|
|
||||||
"rustls-pki-types",
|
|
||||||
"untrusted",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ryu"
|
|
||||||
version = "1.0.17"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "schannel"
|
|
||||||
version = "0.1.23"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534"
|
|
||||||
dependencies = [
|
|
||||||
"windows-sys 0.52.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "scopeguard"
|
|
||||||
version = "1.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "security-framework"
|
|
||||||
version = "2.11.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags 2.5.0",
|
|
||||||
"core-foundation",
|
|
||||||
"core-foundation-sys",
|
|
||||||
"libc",
|
|
||||||
"security-framework-sys",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "security-framework-sys"
|
|
||||||
version = "2.11.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7"
|
|
||||||
dependencies = [
|
|
||||||
"core-foundation-sys",
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[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 = "sha1"
|
|
||||||
version = "0.10.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
"cpufeatures",
|
|
||||||
"digest",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[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 = "shlex"
|
|
||||||
version = "1.3.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "signal-hook"
|
|
||||||
version = "0.3.17"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"signal-hook-registry",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "signal-hook-registry"
|
|
||||||
version = "1.4.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[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 = "slab"
|
|
||||||
version = "0.4.9"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"
|
|
||||||
dependencies = [
|
|
||||||
"autocfg",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[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.7"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c"
|
|
||||||
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 = "sys-locale"
|
|
||||||
version = "0.3.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e801cf239ecd6ccd71f03d270d67dd53d13e90aab208bf4b8fe4ad957ea949b0"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[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 = "tinyvec"
|
|
||||||
version = "1.6.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c55115c6fbe2d2bef26eb09ad74bde02d8255476fc0c7b515ef09fbb35742d82"
|
|
||||||
dependencies = [
|
|
||||||
"tinyvec_macros",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tinyvec_macros"
|
|
||||||
version = "0.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tokio"
|
|
||||||
version = "1.37.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787"
|
|
||||||
dependencies = [
|
|
||||||
"backtrace",
|
|
||||||
"bytes",
|
|
||||||
"libc",
|
|
||||||
"mio",
|
|
||||||
"num_cpus",
|
|
||||||
"parking_lot",
|
|
||||||
"pin-project-lite",
|
|
||||||
"signal-hook-registry",
|
|
||||||
"socket2",
|
|
||||||
"tokio-macros",
|
|
||||||
"windows-sys 0.48.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tokio-macros"
|
|
||||||
version = "2.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn 2.0.60",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tokio-rustls"
|
|
||||||
version = "0.26.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4"
|
|
||||||
dependencies = [
|
|
||||||
"rustls",
|
|
||||||
"rustls-pki-types",
|
|
||||||
"tokio",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tokio-tungstenite"
|
|
||||||
version = "0.23.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c6989540ced10490aaf14e6bad2e3d33728a2813310a0c71d1574304c49631cd"
|
|
||||||
dependencies = [
|
|
||||||
"futures-util",
|
|
||||||
"log",
|
|
||||||
"rustls",
|
|
||||||
"rustls-native-certs",
|
|
||||||
"rustls-pki-types",
|
|
||||||
"tokio",
|
|
||||||
"tokio-rustls",
|
|
||||||
"tungstenite",
|
|
||||||
"webpki-roots",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tun"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"ioctl-sys",
|
|
||||||
"libc",
|
|
||||||
"libloading",
|
|
||||||
"log",
|
|
||||||
"rand",
|
|
||||||
"sha2",
|
|
||||||
"widestring",
|
|
||||||
"winapi",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tungstenite"
|
|
||||||
version = "0.23.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6e2e2ce1e47ed2994fd43b04c8f618008d4cabdd5ee34027cf14f9d918edd9c8"
|
|
||||||
dependencies = [
|
|
||||||
"byteorder",
|
|
||||||
"bytes",
|
|
||||||
"data-encoding",
|
|
||||||
"http 1.1.0",
|
|
||||||
"httparse",
|
|
||||||
"log",
|
|
||||||
"rand",
|
|
||||||
"rustls",
|
|
||||||
"rustls-pki-types",
|
|
||||||
"sha1",
|
|
||||||
"thiserror",
|
|
||||||
"utf-8",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[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-bidi"
|
|
||||||
version = "0.3.15"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unicode-ident"
|
|
||||||
version = "1.0.12"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unicode-normalization"
|
|
||||||
version = "0.1.23"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5"
|
|
||||||
dependencies = [
|
|
||||||
"tinyvec",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unicode-width"
|
|
||||||
version = "0.1.13"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d"
|
|
||||||
|
|
||||||
[[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 = "url"
|
|
||||||
version = "2.5.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c"
|
|
||||||
dependencies = [
|
|
||||||
"form_urlencoded",
|
|
||||||
"idna",
|
|
||||||
"percent-encoding",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "utf-8"
|
|
||||||
version = "0.7.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "uuid"
|
|
||||||
version = "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 = "vn-link"
|
|
||||||
version = "1.2.14"
|
|
||||||
dependencies = [
|
|
||||||
"anyhow",
|
|
||||||
"crossbeam-utils",
|
|
||||||
"log",
|
|
||||||
"lwip-rs",
|
|
||||||
"parking_lot",
|
|
||||||
"tokio",
|
|
||||||
"vnt",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "vn-link-cli"
|
|
||||||
version = "1.2.14"
|
|
||||||
dependencies = [
|
|
||||||
"common",
|
|
||||||
"log",
|
|
||||||
"tokio",
|
|
||||||
"vn-link",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "vnt"
|
|
||||||
version = "1.2.14"
|
|
||||||
dependencies = [
|
|
||||||
"aes",
|
|
||||||
"aes-gcm",
|
|
||||||
"anyhow",
|
|
||||||
"bytes",
|
|
||||||
"cbc",
|
|
||||||
"cfg_aliases",
|
|
||||||
"chacha20",
|
|
||||||
"chacha20poly1305",
|
|
||||||
"crossbeam-epoch",
|
|
||||||
"crossbeam-queue",
|
|
||||||
"crossbeam-utils",
|
|
||||||
"dns-parser",
|
|
||||||
"ecb",
|
|
||||||
"fnv",
|
|
||||||
"futures-util",
|
|
||||||
"igd",
|
|
||||||
"libc",
|
|
||||||
"libloading",
|
|
||||||
"libsm",
|
|
||||||
"log",
|
|
||||||
"lz4_flex",
|
|
||||||
"mio",
|
|
||||||
"network-interface",
|
|
||||||
"openssl-sys",
|
|
||||||
"packet",
|
|
||||||
"parking_lot",
|
|
||||||
"protobuf",
|
|
||||||
"protobuf-codegen",
|
|
||||||
"protoc-bin-vendored",
|
|
||||||
"rand",
|
|
||||||
"ring",
|
|
||||||
"rsa",
|
|
||||||
"rustls",
|
|
||||||
"sha2",
|
|
||||||
"socket2",
|
|
||||||
"spki",
|
|
||||||
"stun-format",
|
|
||||||
"thiserror",
|
|
||||||
"tokio",
|
|
||||||
"tokio-tungstenite",
|
|
||||||
"tun",
|
|
||||||
"windows-sys 0.59.0",
|
|
||||||
"zstd",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "vnt-cli"
|
|
||||||
version = "1.2.14"
|
|
||||||
dependencies = [
|
|
||||||
"anyhow",
|
|
||||||
"chrono",
|
|
||||||
"common",
|
|
||||||
"console",
|
|
||||||
"log",
|
|
||||||
"rand",
|
|
||||||
"signal-hook",
|
|
||||||
"sudo",
|
|
||||||
"vnt",
|
|
||||||
"winapi",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[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 = "webpki-roots"
|
|
||||||
version = "0.26.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "bd7c23921eeb1713a4e851530e9b9756e4fb0e89978582942612524cf09f01cd"
|
|
||||||
dependencies = [
|
|
||||||
"rustls-pki-types",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[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 = "wildmatch"
|
|
||||||
version = "1.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7f44b95f62d34113cf558c93511ac93027e03e9c29a60dd0fd70e6e025c7270a"
|
|
||||||
|
|
||||||
[[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-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.6",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[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.6",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-sys"
|
|
||||||
version = "0.59.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
|
|
||||||
dependencies = [
|
|
||||||
"windows-targets 0.52.6",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[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.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
|
||||||
dependencies = [
|
|
||||||
"windows_aarch64_gnullvm 0.52.6",
|
|
||||||
"windows_aarch64_msvc 0.52.6",
|
|
||||||
"windows_i686_gnu 0.52.6",
|
|
||||||
"windows_i686_gnullvm",
|
|
||||||
"windows_i686_msvc 0.52.6",
|
|
||||||
"windows_x86_64_gnu 0.52.6",
|
|
||||||
"windows_x86_64_gnullvm 0.52.6",
|
|
||||||
"windows_x86_64_msvc 0.52.6",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[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.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
|
||||||
|
|
||||||
[[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.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
|
||||||
|
|
||||||
[[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.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_i686_gnullvm"
|
|
||||||
version = "0.52.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
|
||||||
|
|
||||||
[[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.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
|
||||||
|
|
||||||
[[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.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
|
||||||
|
|
||||||
[[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.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
|
||||||
|
|
||||||
[[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.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "xml-rs"
|
|
||||||
version = "0.8.20"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "791978798f0597cfc70478424c2b4fdc2b7a8024aaff78497ef00f24ef674193"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "xmltree"
|
|
||||||
version = "0.10.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d7d8a75eaf6557bb84a65ace8609883db44a29951042ada9b393151532e41fcb"
|
|
||||||
dependencies = [
|
|
||||||
"xml-rs",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[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"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "zstd"
|
|
||||||
version = "0.13.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2d789b1514203a1120ad2429eae43a7bd32b90976a7bb8a05f7ec02fa88cc23a"
|
|
||||||
dependencies = [
|
|
||||||
"zstd-safe",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "zstd-safe"
|
|
||||||
version = "7.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1cd99b45c6bc03a018c8b8a86025678c87e55526064e38f9df301989dce7ec0a"
|
|
||||||
dependencies = [
|
|
||||||
"zstd-sys",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "zstd-sys"
|
|
||||||
version = "2.0.10+zstd.1.5.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c253a4914af5bafc8fa8c86ee400827e83cf6ec01195ec1f1ed8441bf00d65aa"
|
|
||||||
dependencies = [
|
|
||||||
"cc",
|
|
||||||
"pkg-config",
|
|
||||||
]
|
|
||||||
@@ -195,6 +195,8 @@ QQ群1: 1034868233(满人)
|
|||||||
|
|
||||||
QQ群2: 950473757
|
QQ群2: 950473757
|
||||||
|
|
||||||
|
QQ群3: 1060550456
|
||||||
|
|
||||||
### 赞助
|
### 赞助
|
||||||
|
|
||||||
如果VNT对你有帮助,欢迎打赏作者
|
如果VNT对你有帮助,欢迎打赏作者
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "common"
|
name = "common"
|
||||||
version = "1.2.14"
|
version = "1.2.16"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|||||||
+3
-9
@@ -141,9 +141,6 @@ pub fn parse_args_config() -> anyhow::Result<Option<(Config, Vec<String>, bool)>
|
|||||||
print_usage(&program, opts);
|
print_usage(&program, opts);
|
||||||
return Err(anyhow::anyhow!("parameter -k not found ."));
|
return Err(anyhow::anyhow!("parameter -k not found ."));
|
||||||
}
|
}
|
||||||
#[cfg(target_os = "windows")]
|
|
||||||
#[cfg(feature = "integrated_tun")]
|
|
||||||
let tap = matches.opt_present("a");
|
|
||||||
#[cfg(feature = "integrated_tun")]
|
#[cfg(feature = "integrated_tun")]
|
||||||
let device_name = matches.opt_str("nic");
|
let device_name = matches.opt_str("nic");
|
||||||
let token: String = matches.opt_get("k").unwrap().unwrap();
|
let token: String = matches.opt_get("k").unwrap().unwrap();
|
||||||
@@ -298,7 +295,7 @@ pub fn parse_args_config() -> anyhow::Result<Option<(Config, Vec<String>, bool)>
|
|||||||
let config = Config::new(
|
let config = Config::new(
|
||||||
#[cfg(feature = "integrated_tun")]
|
#[cfg(feature = "integrated_tun")]
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
tap,
|
false,
|
||||||
token,
|
token,
|
||||||
device_id,
|
device_id,
|
||||||
name,
|
name,
|
||||||
@@ -351,7 +348,6 @@ fn get_description(key: &str, language: &str) -> String {
|
|||||||
("-d <id>", ("设备唯一标识符,不使用--ip参数时,服务端凭此参数分配虚拟ip,注意不能重复", "Device unique identifier, used by the server to allocate virtual IP when --ip parameter is not used, must be unique")),
|
("-d <id>", ("设备唯一标识符,不使用--ip参数时,服务端凭此参数分配虚拟ip,注意不能重复", "Device unique identifier, used by the server to allocate virtual IP when --ip parameter is not used, must be unique")),
|
||||||
("-s <server>", ("注册和中继服务器地址,协议支持使用tcp://和ws://和wss://,默认为udp://", "Registration and relay server address, protocols support using tcp://, ws://, and wss://, default is udp://")),
|
("-s <server>", ("注册和中继服务器地址,协议支持使用tcp://和ws://和wss://,默认为udp://", "Registration and relay server address, protocols support using tcp://, ws://, and wss://, default is udp://")),
|
||||||
("-e <stun-server>", ("stun服务器,用于探测NAT类型,可使用多个地址,如-e stun.miwifi.com -e turn.cloudflare.com", "STUN server for detecting NAT type, can specify multiple addresses, e.g., -e stun.miwifi.com -e turn.cloudflare.com")),
|
("-e <stun-server>", ("stun服务器,用于探测NAT类型,可使用多个地址,如-e stun.miwifi.com -e turn.cloudflare.com", "STUN server for detecting NAT type, can specify multiple addresses, e.g., -e stun.miwifi.com -e turn.cloudflare.com")),
|
||||||
("-a", ("使用tap模式,默认使用tun模式,使用tap时需要配合'--nic'参数指定tap网卡", "Use tap mode, default is tun mode, specify '--nic' parameter with tap network card")),
|
|
||||||
("-i <in-ip>", ("配置点对网(IP代理)时使用,-i 192.168.0.0/24,10.26.0.3表示允许接收网段192.168.0.0/24的数据并转发到10.26.0.3,可指定多个网段", "Used when configuring point-to-point network (IP proxy), -i 192.168.0.0/24,10.26.0.3 allows receiving data from subnet 192.168.0.0/24 and forwarding to 10.26.0.3, specify multiple subnets")),
|
("-i <in-ip>", ("配置点对网(IP代理)时使用,-i 192.168.0.0/24,10.26.0.3表示允许接收网段192.168.0.0/24的数据并转发到10.26.0.3,可指定多个网段", "Used when configuring point-to-point network (IP proxy), -i 192.168.0.0/24,10.26.0.3 allows receiving data from subnet 192.168.0.0/24 and forwarding to 10.26.0.3, specify multiple subnets")),
|
||||||
("-o <out-ip>", ("配置点对网时使用,-o 192.168.0.0/24表示允许将数据转发到192.168.0.0/24,可指定多个网段", "Used when configuring point-to-point network, -o 192.168.0.0/24 allows forwarding data to 192.168.0.0/24, specify multiple subnets")),
|
("-o <out-ip>", ("配置点对网时使用,-o 192.168.0.0/24表示允许将数据转发到192.168.0.0/24,可指定多个网段", "Used when configuring point-to-point network, -o 192.168.0.0/24 allows forwarding data to 192.168.0.0/24, specify multiple subnets")),
|
||||||
("-w <password>", ("使用该密码生成的密钥对客户端数据进行加密,并且服务端无法解密,使用相同密码的客户端才能通信", "Encrypt client data with keys generated by this password, server cannot decrypt, clients must use the same password to communicate")),
|
("-w <password>", ("使用该密码生成的密钥对客户端数据进行加密,并且服务端无法解密,使用相同密码的客户端才能通信", "Encrypt client data with keys generated by this password, server cannot decrypt, clients must use the same password to communicate")),
|
||||||
@@ -430,9 +426,7 @@ fn print_usage(program: &str, _opts: Options) {
|
|||||||
" -e <stun-server> {}",
|
" -e <stun-server> {}",
|
||||||
get_description("-e <stun-server>", &language)
|
get_description("-e <stun-server>", &language)
|
||||||
);
|
);
|
||||||
#[cfg(target_os = "windows")]
|
|
||||||
#[cfg(feature = "integrated_tun")]
|
|
||||||
println!(" -a {}", get_description("-a", &language));
|
|
||||||
println!(
|
println!(
|
||||||
" -i <in-ip> {}",
|
" -i <in-ip> {}",
|
||||||
get_description("-i <in-ip>", &language)
|
get_description("-i <in-ip>", &language)
|
||||||
@@ -517,7 +511,7 @@ fn print_usage(program: &str, _opts: Options) {
|
|||||||
" --use-channel <p2p> {}",
|
" --use-channel <p2p> {}",
|
||||||
get_description("--use-channel <p2p>", &language)
|
get_description("--use-channel <p2p>", &language)
|
||||||
);
|
);
|
||||||
#[cfg(not(feature = "vn-link-model"))]
|
#[cfg(feature = "integrated_tun")]
|
||||||
println!(
|
println!(
|
||||||
" --nic <tun0> {}",
|
" --nic <tun0> {}",
|
||||||
get_description("--nic <tun0>", &language)
|
get_description("--nic <tun0>", &language)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "vn-link-cli"
|
name = "vn-link-cli"
|
||||||
version = "1.2.14"
|
version = "1.2.16"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
@@ -9,6 +9,9 @@ common = { path = "../common", default-features = false }
|
|||||||
tokio = { version = "1.37.0", features = ["full"] }
|
tokio = { version = "1.37.0", features = ["full"] }
|
||||||
log = "0.4.17"
|
log = "0.4.17"
|
||||||
|
|
||||||
|
[target.'cfg(windows)'.build-dependencies]
|
||||||
|
thunk-rs = { version = "0.3.3", features = ["win7"] }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["default-feature"]
|
default = ["default-feature"]
|
||||||
default-feature = ["server_encrypt", "aes_gcm", "aes_cbc", "aes_ecb", "sm4_cbc", "chacha20_poly1305", "port_mapping", "log", "command", "file_config", "lz4", "ws"]
|
default-feature = ["server_encrypt", "aes_gcm", "aes_cbc", "aes_ecb", "sm4_cbc", "chacha20_poly1305", "port_mapping", "log", "command", "file_config", "lz4", "ws"]
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
fn main() {
|
||||||
|
// 配置 thunk-rs 来链接 Windows 7 兼容库,并自动设置链接参数
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
thunk::thunk();
|
||||||
|
}
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "vn-link"
|
name = "vn-link"
|
||||||
version = "1.2.14"
|
version = "1.2.16"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|||||||
+5
-1
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "vnt-cli"
|
name = "vnt-cli"
|
||||||
version = "1.2.14"
|
version = "1.2.16"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
@@ -19,6 +19,7 @@ signal-hook = "0.3.17"
|
|||||||
[target.'cfg(target_os = "windows")'.dependencies]
|
[target.'cfg(target_os = "windows")'.dependencies]
|
||||||
winapi = { version = "0.3.9", features = ["handleapi", "processthreadsapi", "winnt", "securitybaseapi", "impl-default"] }
|
winapi = { version = "0.3.9", features = ["handleapi", "processthreadsapi", "winnt", "securitybaseapi", "impl-default"] }
|
||||||
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["default-feature"]
|
default = ["default-feature"]
|
||||||
default-feature = ["server_encrypt", "aes_gcm", "aes_cbc", "aes_ecb", "sm4_cbc", "chacha20_poly1305", "ip_proxy", "port_mapping", "log", "command", "file_config", "lz4", "ws"]
|
default-feature = ["server_encrypt", "aes_gcm", "aes_cbc", "aes_ecb", "sm4_cbc", "chacha20_poly1305", "ip_proxy", "port_mapping", "log", "command", "file_config", "lz4", "ws"]
|
||||||
@@ -45,3 +46,6 @@ file_config = ["common/file_config"]
|
|||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
chrono = "0.4.23"
|
chrono = "0.4.23"
|
||||||
|
|
||||||
|
[target.'cfg(windows)'.build-dependencies]
|
||||||
|
thunk-rs = { version = "0.3.3", features = ["win7"] }
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
fn main() {
|
||||||
|
// 配置 thunk-rs 来链接 Windows 7 兼容库,并自动设置链接参数
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
thunk::thunk();
|
||||||
|
}
|
||||||
+9
-7
@@ -1,12 +1,12 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "vnt"
|
name = "vnt"
|
||||||
version = "1.2.14"
|
version = "1.2.16"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
tun = { path = "tun", optional = true }
|
tun-rs = { version = "2.5.0", optional = true, features = ["interruptible"] }
|
||||||
packet = { path = "./packet" }
|
packet = { path = "./packet" }
|
||||||
bytes = "1.5.0"
|
bytes = "1.5.0"
|
||||||
log = "0.4.17"
|
log = "0.4.17"
|
||||||
@@ -31,13 +31,14 @@ rsa = { version = "0.9.2", features = [], optional = true }
|
|||||||
spki = { version = "0.7.2", features = ["fingerprint", "alloc", "base64"], optional = true }
|
spki = { version = "0.7.2", features = ["fingerprint", "alloc", "base64"], optional = true }
|
||||||
openssl-sys = { git = "https://github.com/vnt-dev/rust-openssl", optional = true }
|
openssl-sys = { git = "https://github.com/vnt-dev/rust-openssl", optional = true }
|
||||||
libsm = { git = "https://github.com/vnt-dev/libsm", optional = true }
|
libsm = { git = "https://github.com/vnt-dev/libsm", optional = true }
|
||||||
|
http_req = { git = "https://github.com/lmq8267/http_req.git", default-features = false, features = ["rust-tls"] }
|
||||||
|
|
||||||
mio = { version = "=0.8.11", features = ["os-poll", "net", "os-ext"] }
|
mio = { version = "=0.8.11", features = ["os-poll", "net", "os-ext"] }
|
||||||
crossbeam-queue = "0.3.11"
|
crossbeam-queue = "0.3.11"
|
||||||
anyhow = "1.0.82"
|
anyhow = "1.0.82"
|
||||||
dns-parser = "0.8.0"
|
dns-parser = "0.8.0"
|
||||||
|
|
||||||
tokio = { version = "1.37.0", features = ["full"] }
|
tokio = { version = "1.46.1", features = ["full"] }
|
||||||
|
|
||||||
lz4_flex = { version = "0.11", default-features = false, optional = true }
|
lz4_flex = { version = "0.11", default-features = false, optional = true }
|
||||||
zstd = { version = "0.13.1", optional = true }
|
zstd = { version = "0.13.1", optional = true }
|
||||||
@@ -45,20 +46,21 @@ zstd = { version = "0.13.1", optional = true }
|
|||||||
fnv = "1.0.7"
|
fnv = "1.0.7"
|
||||||
igd = { version = "0.12.1", optional = true }
|
igd = { version = "0.12.1", optional = true }
|
||||||
tokio-tungstenite = { version = "0.23.1", optional = true }
|
tokio-tungstenite = { version = "0.23.1", optional = true }
|
||||||
rustls = { version = "0.23.0", features = ["ring"], default-features = false, optional = true }
|
rustls = { version = "0.23.0", features = ["ring", "tls12"], default-features = false, optional = true }
|
||||||
|
|
||||||
network-interface = "2.0.0"
|
network-interface = "2.0.0"
|
||||||
|
|
||||||
futures-util = "0.3.30"
|
futures-util = "0.3.30"
|
||||||
[target.'cfg(target_os = "windows")'.dependencies]
|
[target.'cfg(target_os = "windows")'.dependencies]
|
||||||
|
winreg = "0.55.0"
|
||||||
libloading = "0.8.0"
|
libloading = "0.8.0"
|
||||||
windows-sys = {version = "0.59.0",features = [ "Win32_Foundation",
|
windows-sys = { version = "0.60.2", features = ["Win32_Foundation",
|
||||||
"Win32_NetworkManagement",
|
"Win32_NetworkManagement",
|
||||||
"Win32_NetworkManagement_IpHelper",
|
"Win32_NetworkManagement_IpHelper",
|
||||||
"Win32_Networking_WinSock",
|
"Win32_Networking_WinSock",
|
||||||
"Win32_System_IO",
|
"Win32_System_IO",
|
||||||
"Win32_System_Threading",
|
"Win32_System_Threading",
|
||||||
"Win32_System_WindowsProgramming",]}
|
"Win32_System_WindowsProgramming", ] }
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
protobuf-codegen = "=3.2.0"
|
protobuf-codegen = "=3.2.0"
|
||||||
@@ -81,7 +83,7 @@ ip_proxy = []
|
|||||||
port_mapping = []
|
port_mapping = []
|
||||||
lz4_compress = ["lz4_flex"]
|
lz4_compress = ["lz4_flex"]
|
||||||
zstd_compress = ["zstd"]
|
zstd_compress = ["zstd"]
|
||||||
integrated_tun = ["tun"]
|
integrated_tun = ["tun-rs"]
|
||||||
upnp = ["igd"]
|
upnp = ["igd"]
|
||||||
ws = ["tokio-tungstenite"]
|
ws = ["tokio-tungstenite"]
|
||||||
wss = ["ws", "tokio-tungstenite/rustls-tls-native-roots", "tokio-tungstenite/rustls-tls-webpki-roots", "rustls"]
|
wss = ["ws", "tokio-tungstenite/rustls-tls-native-roots", "tokio-tungstenite/rustls-tls-webpki-roots", "rustls"]
|
||||||
@@ -103,7 +103,16 @@ where
|
|||||||
if let Ok(redirect) = v.to_str() {
|
if let Ok(redirect) = v.to_str() {
|
||||||
log::info!("url重定向响应头 {:?}", res.headers());
|
log::info!("url重定向响应头 {:?}", res.headers());
|
||||||
log::info!("url重定向地址 {}", redirect);
|
log::info!("url重定向地址 {}", redirect);
|
||||||
url = redirect.to_string();
|
// 替换协议前缀
|
||||||
|
if redirect.starts_with("http://") {
|
||||||
|
url = redirect.replacen("http://", "ws://", 1);
|
||||||
|
} else if redirect.starts_with("https://") {
|
||||||
|
url = redirect.replacen("https://", "wss://", 1);
|
||||||
|
} else {
|
||||||
|
url = redirect.to_string();
|
||||||
|
}
|
||||||
|
println!("Location:{}", url);
|
||||||
|
log::info!("修改后的重定向地址: {}", url);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -313,7 +313,7 @@ impl VntInner {
|
|||||||
let client_cipher = client_cipher.clone();
|
let client_cipher = client_cipher.clone();
|
||||||
let server_cipher = server_cipher.clone();
|
let server_cipher = server_cipher.clone();
|
||||||
//延迟启动
|
//延迟启动
|
||||||
scheduler.timeout(Duration::from_secs(3), move |scheduler| {
|
scheduler.timeout(Duration::from_secs(1), move |scheduler| {
|
||||||
start(
|
start(
|
||||||
scheduler,
|
scheduler,
|
||||||
context,
|
context,
|
||||||
|
|||||||
+18
-11
@@ -96,15 +96,6 @@ impl Config {
|
|||||||
allow_wire_guard: bool,
|
allow_wire_guard: bool,
|
||||||
local_dev: Option<String>,
|
local_dev: Option<String>,
|
||||||
) -> anyhow::Result<Self> {
|
) -> anyhow::Result<Self> {
|
||||||
#[cfg(windows)]
|
|
||||||
#[cfg(feature = "integrated_tun")]
|
|
||||||
if !tap {
|
|
||||||
if let Err(e) = tun::Device::check_tun_dll() {
|
|
||||||
log::warn!("校验平台dll {:?}", e);
|
|
||||||
Err(e)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for x in stun_server.iter_mut() {
|
for x in stun_server.iter_mut() {
|
||||||
if !x.contains(":") {
|
if !x.contains(":") {
|
||||||
x.push_str(":3478");
|
x.push_str(":3478");
|
||||||
@@ -150,12 +141,28 @@ impl Config {
|
|||||||
server_address_str = s.to_string();
|
server_address_str = s.to_string();
|
||||||
protocol = ConnectProtocol::TCP;
|
protocol = ConnectProtocol::TCP;
|
||||||
}
|
}
|
||||||
server_address = address_choose(dns_query_all(
|
let address_result = dns_query_all(
|
||||||
&server_address_str,
|
&server_address_str,
|
||||||
name_servers.clone(),
|
name_servers.clone(),
|
||||||
&LocalInterface::default(),
|
&LocalInterface::default(),
|
||||||
)?)?;
|
);
|
||||||
|
match address_result {
|
||||||
|
Ok(address) => match address_choose(address) {
|
||||||
|
Ok(resolved_address) => {
|
||||||
|
server_address = resolved_address;
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
log::error!("Failed to choose address: {}", e);
|
||||||
|
println!("Failed to choose address: {}", e);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(e) => {
|
||||||
|
log::error!("DNS query failed: {}", e);
|
||||||
|
println!("DNS query failed: {}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "port_mapping")]
|
#[cfg(feature = "port_mapping")]
|
||||||
let port_mapping_list = crate::port_mapping::convert(port_mapping_list)?;
|
let port_mapping_list = crate::port_mapping::convert(port_mapping_list)?;
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ pub fn idle_gateway<Call: VntCallback>(
|
|||||||
&mut connect_count,
|
&mut connect_count,
|
||||||
&handshake,
|
&handshake,
|
||||||
);
|
);
|
||||||
let rs = scheduler.timeout(Duration::from_secs(5), move |s| {
|
let rs = scheduler.timeout(Duration::from_secs(8), move |s| {
|
||||||
idle_gateway(
|
idle_gateway(
|
||||||
s,
|
s,
|
||||||
context,
|
context,
|
||||||
|
|||||||
@@ -7,12 +7,11 @@ use std::sync::Arc;
|
|||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
use crossbeam_utils::atomic::AtomicCell;
|
use crossbeam_utils::atomic::AtomicCell;
|
||||||
use parking_lot::Mutex;
|
|
||||||
use protobuf::Message;
|
|
||||||
|
|
||||||
use packet::icmp::{icmp, Kind};
|
use packet::icmp::{icmp, Kind};
|
||||||
use packet::ip::ipv4;
|
use packet::ip::ipv4;
|
||||||
use packet::ip::ipv4::packet::IpV4Packet;
|
use packet::ip::ipv4::packet::IpV4Packet;
|
||||||
|
use parking_lot::Mutex;
|
||||||
|
use protobuf::Message;
|
||||||
|
|
||||||
use crate::channel::context::ChannelContext;
|
use crate::channel::context::ChannelContext;
|
||||||
use crate::channel::{Route, RouteKey};
|
use crate::channel::{Route, RouteKey};
|
||||||
@@ -360,10 +359,9 @@ impl<Call: VntCallback, Device: DeviceWrite> ServerPacketHandler<Call, Device> {
|
|||||||
&self.callback,
|
&self.callback,
|
||||||
) {
|
) {
|
||||||
Ok(device) => {
|
Ok(device) => {
|
||||||
use tun::device::IFace;
|
|
||||||
let tun_info = crate::handle::callback::DeviceInfo::new(
|
let tun_info = crate::handle::callback::DeviceInfo::new(
|
||||||
device.name().unwrap_or("unknown".into()),
|
device.name().unwrap_or("unknown".into()),
|
||||||
device.version().unwrap_or("unknown".into()),
|
"".into(),
|
||||||
);
|
);
|
||||||
log::info!("tun信息{:?}", tun_info);
|
log::info!("tun信息{:?}", tun_info);
|
||||||
self.callback.create_tun(tun_info);
|
self.callback.create_tun(tun_info);
|
||||||
@@ -392,24 +390,16 @@ impl<Call: VntCallback, Device: DeviceWrite> ServerPacketHandler<Call, Device> {
|
|||||||
"device_fd == 0".into(),
|
"device_fd == 0".into(),
|
||||||
));
|
));
|
||||||
} else {
|
} else {
|
||||||
match tun::Device::new(device_fd as _) {
|
let device =
|
||||||
Ok(device) => {
|
unsafe { tun_rs::SyncDevice::from_fd(device_fd as _) };
|
||||||
if let Err(e) = self.tun_device_helper.start(
|
if let Err(e) = self
|
||||||
Arc::new(device),
|
.tun_device_helper
|
||||||
self.config_info.allow_wire_guard,
|
.start(Arc::new(device), self.config_info.allow_wire_guard)
|
||||||
) {
|
{
|
||||||
self.callback.error(ErrorInfo::new_msg(
|
self.callback.error(ErrorInfo::new_msg(
|
||||||
ErrorType::FailedToCrateDevice,
|
ErrorType::FailedToCrateDevice,
|
||||||
format!("{:?}", e),
|
format!("{:?}", e),
|
||||||
));
|
));
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
self.callback.error(ErrorInfo::new_msg(
|
|
||||||
ErrorType::FailedToCrateDevice,
|
|
||||||
format!("{:?}", e),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,11 @@
|
|||||||
pub mod tun_handler;
|
pub mod tun_handler;
|
||||||
|
|
||||||
#[cfg(unix)]
|
|
||||||
mod unix;
|
|
||||||
|
|
||||||
use crossbeam_utils::atomic::AtomicCell;
|
use crossbeam_utils::atomic::AtomicCell;
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
#[cfg(unix)]
|
mod platform;
|
||||||
pub(crate) use unix::*;
|
|
||||||
|
|
||||||
#[cfg(target_os = "windows")]
|
pub(crate) use platform::*;
|
||||||
mod windows;
|
|
||||||
|
|
||||||
#[cfg(target_os = "windows")]
|
|
||||||
pub(crate) use windows::*;
|
|
||||||
|
|
||||||
/// 仅仅是停止tun,不停止vnt
|
/// 仅仅是停止tun,不停止vnt
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
|
|||||||
@@ -13,13 +13,12 @@ use parking_lot::Mutex;
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::net::Ipv4Addr;
|
use std::net::Ipv4Addr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tun::device::IFace;
|
use tun_rs::{InterruptEvent, SyncDevice};
|
||||||
use tun::Device;
|
|
||||||
|
|
||||||
pub(crate) fn start_simple(
|
pub(crate) fn start_simple(
|
||||||
stop_manager: StopManager,
|
stop_manager: StopManager,
|
||||||
context: &ChannelContext,
|
context: &ChannelContext,
|
||||||
device: Arc<Device>,
|
device: Arc<SyncDevice>,
|
||||||
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
|
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
|
||||||
ip_route: ExternalRoute,
|
ip_route: ExternalRoute,
|
||||||
#[cfg(feature = "ip_proxy")] ip_proxy_map: Option<IpProxyMap>,
|
#[cfg(feature = "ip_proxy")] ip_proxy_map: Option<IpProxyMap>,
|
||||||
@@ -30,10 +29,11 @@ pub(crate) fn start_simple(
|
|||||||
device_stop: DeviceStop,
|
device_stop: DeviceStop,
|
||||||
allow_wire_guard: bool,
|
allow_wire_guard: bool,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
|
let event = Arc::new(InterruptEvent::new()?);
|
||||||
let worker = {
|
let worker = {
|
||||||
let device = device.clone();
|
let event = event.clone();
|
||||||
stop_manager.add_listener("tun_device".into(), move || {
|
stop_manager.add_listener("tun_device".into(), move || {
|
||||||
if let Err(e) = device.shutdown() {
|
if let Err(e) = event.trigger() {
|
||||||
log::warn!("{:?}", e);
|
log::warn!("{:?}", e);
|
||||||
}
|
}
|
||||||
})?
|
})?
|
||||||
@@ -51,6 +51,7 @@ pub(crate) fn start_simple(
|
|||||||
if let Err(e) = start_simple0(
|
if let Err(e) = start_simple0(
|
||||||
context,
|
context,
|
||||||
device,
|
device,
|
||||||
|
event,
|
||||||
current_device,
|
current_device,
|
||||||
ip_route,
|
ip_route,
|
||||||
#[cfg(feature = "ip_proxy")]
|
#[cfg(feature = "ip_proxy")]
|
||||||
@@ -72,7 +73,8 @@ pub(crate) fn start_simple(
|
|||||||
|
|
||||||
fn start_simple0(
|
fn start_simple0(
|
||||||
context: &ChannelContext,
|
context: &ChannelContext,
|
||||||
device: Arc<Device>,
|
device: Arc<SyncDevice>,
|
||||||
|
event: Arc<InterruptEvent>,
|
||||||
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
|
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
|
||||||
ip_route: ExternalRoute,
|
ip_route: ExternalRoute,
|
||||||
#[cfg(feature = "ip_proxy")] ip_proxy_map: Option<IpProxyMap>,
|
#[cfg(feature = "ip_proxy")] ip_proxy_map: Option<IpProxyMap>,
|
||||||
@@ -85,8 +87,7 @@ fn start_simple0(
|
|||||||
let mut buf = [0; BUFFER_SIZE];
|
let mut buf = [0; BUFFER_SIZE];
|
||||||
let mut extend = [0; BUFFER_SIZE];
|
let mut extend = [0; BUFFER_SIZE];
|
||||||
loop {
|
loop {
|
||||||
let len = device.read(&mut buf[12..])? + 12;
|
let len = device.recv_intr(&mut buf[12..],&event)? + 12;
|
||||||
//单线程的
|
|
||||||
// buf是重复利用的,需要重置头部
|
// buf是重复利用的,需要重置头部
|
||||||
buf[..12].fill(0);
|
buf[..12].fill(0);
|
||||||
match crate::handle::tun_tap::tun_handler::handle(
|
match crate::handle::tun_tap::tun_handler::handle(
|
||||||
@@ -1,16 +1,14 @@
|
|||||||
use crossbeam_utils::atomic::AtomicCell;
|
use crossbeam_utils::atomic::AtomicCell;
|
||||||
|
use packet::icmp::icmp::IcmpPacket;
|
||||||
|
use packet::icmp::Kind;
|
||||||
|
use packet::ip::ipv4::packet::IpV4Packet;
|
||||||
|
use packet::ip::ipv4::protocol::Protocol;
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::net::Ipv4Addr;
|
use std::net::Ipv4Addr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::{io, thread};
|
use std::{io, thread};
|
||||||
|
use tun_rs::SyncDevice;
|
||||||
use packet::icmp::icmp::IcmpPacket;
|
|
||||||
use packet::icmp::Kind;
|
|
||||||
use packet::ip::ipv4::packet::IpV4Packet;
|
|
||||||
use packet::ip::ipv4::protocol::Protocol;
|
|
||||||
use tun::device::IFace;
|
|
||||||
use tun::Device;
|
|
||||||
|
|
||||||
use crate::channel::context::ChannelContext;
|
use crate::channel::context::ChannelContext;
|
||||||
use crate::channel::sender::{send_to_wg, send_to_wg_broadcast};
|
use crate::channel::sender::{send_to_wg, send_to_wg_broadcast};
|
||||||
@@ -28,7 +26,7 @@ use crate::protocol::body::ENCRYPTION_RESERVED;
|
|||||||
use crate::protocol::ip_turn_packet::BroadcastPacket;
|
use crate::protocol::ip_turn_packet::BroadcastPacket;
|
||||||
use crate::protocol::{ip_turn_packet, NetPacket, MAX_TTL};
|
use crate::protocol::{ip_turn_packet, NetPacket, MAX_TTL};
|
||||||
use crate::util::StopManager;
|
use crate::util::StopManager;
|
||||||
fn icmp(device_writer: &Device, mut ipv4_packet: IpV4Packet<&mut [u8]>) -> anyhow::Result<()> {
|
fn icmp(device_writer: &SyncDevice, mut ipv4_packet: IpV4Packet<&mut [u8]>) -> anyhow::Result<()> {
|
||||||
if ipv4_packet.protocol() == Protocol::Icmp {
|
if ipv4_packet.protocol() == Protocol::Icmp {
|
||||||
let mut icmp = IcmpPacket::new(ipv4_packet.payload_mut())?;
|
let mut icmp = IcmpPacket::new(ipv4_packet.payload_mut())?;
|
||||||
if icmp.kind() == Kind::EchoRequest {
|
if icmp.kind() == Kind::EchoRequest {
|
||||||
@@ -38,7 +36,7 @@ fn icmp(device_writer: &Device, mut ipv4_packet: IpV4Packet<&mut [u8]>) -> anyho
|
|||||||
ipv4_packet.set_source_ip(ipv4_packet.destination_ip());
|
ipv4_packet.set_source_ip(ipv4_packet.destination_ip());
|
||||||
ipv4_packet.set_destination_ip(src);
|
ipv4_packet.set_destination_ip(src);
|
||||||
ipv4_packet.update_checksum();
|
ipv4_packet.update_checksum();
|
||||||
device_writer.write(ipv4_packet.buffer)?;
|
device_writer.send(ipv4_packet.buffer)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -47,7 +45,7 @@ fn icmp(device_writer: &Device, mut ipv4_packet: IpV4Packet<&mut [u8]>) -> anyho
|
|||||||
pub fn start(
|
pub fn start(
|
||||||
stop_manager: StopManager,
|
stop_manager: StopManager,
|
||||||
context: ChannelContext,
|
context: ChannelContext,
|
||||||
device: Arc<Device>,
|
device: Arc<SyncDevice>,
|
||||||
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
|
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
|
||||||
ip_route: ExternalRoute,
|
ip_route: ExternalRoute,
|
||||||
#[cfg(feature = "ip_proxy")] ip_proxy_map: Option<IpProxyMap>,
|
#[cfg(feature = "ip_proxy")] ip_proxy_map: Option<IpProxyMap>,
|
||||||
@@ -160,7 +158,7 @@ pub(crate) fn handle(
|
|||||||
buf: &mut [u8],
|
buf: &mut [u8],
|
||||||
data_len: usize, //数据总长度=12+ip包长度
|
data_len: usize, //数据总长度=12+ip包长度
|
||||||
extend: &mut [u8],
|
extend: &mut [u8],
|
||||||
device_writer: &Device,
|
device_writer: &SyncDevice,
|
||||||
current_device: CurrentDeviceInfo,
|
current_device: CurrentDeviceInfo,
|
||||||
ip_route: &ExternalRoute,
|
ip_route: &ExternalRoute,
|
||||||
#[cfg(feature = "ip_proxy")] proxy_map: &Option<IpProxyMap>,
|
#[cfg(feature = "ip_proxy")] proxy_map: &Option<IpProxyMap>,
|
||||||
|
|||||||
@@ -1,154 +0,0 @@
|
|||||||
use crate::channel::context::ChannelContext;
|
|
||||||
use crate::channel::BUFFER_SIZE;
|
|
||||||
use crate::cipher::Cipher;
|
|
||||||
use crate::compression::Compressor;
|
|
||||||
use crate::external_route::ExternalRoute;
|
|
||||||
use crate::handle::tun_tap::DeviceStop;
|
|
||||||
use crate::handle::{CurrentDeviceInfo, PeerDeviceInfo};
|
|
||||||
#[cfg(feature = "ip_proxy")]
|
|
||||||
use crate::ip_proxy::IpProxyMap;
|
|
||||||
use crate::util::StopManager;
|
|
||||||
use crossbeam_utils::atomic::AtomicCell;
|
|
||||||
use mio::event::Source;
|
|
||||||
use mio::unix::SourceFd;
|
|
||||||
use mio::{Events, Interest, Poll, Token, Waker};
|
|
||||||
use parking_lot::Mutex;
|
|
||||||
use std::collections::HashMap;
|
|
||||||
use std::io;
|
|
||||||
use std::net::Ipv4Addr;
|
|
||||||
use std::os::fd::AsRawFd;
|
|
||||||
use std::sync::Arc;
|
|
||||||
use tun::Device;
|
|
||||||
|
|
||||||
const STOP: Token = Token(0);
|
|
||||||
const FD: Token = Token(1);
|
|
||||||
|
|
||||||
pub(crate) fn start_simple(
|
|
||||||
stop_manager: StopManager,
|
|
||||||
context: &ChannelContext,
|
|
||||||
device: Arc<Device>,
|
|
||||||
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
|
|
||||||
ip_route: ExternalRoute,
|
|
||||||
#[cfg(feature = "ip_proxy")] ip_proxy_map: Option<IpProxyMap>,
|
|
||||||
client_cipher: Cipher,
|
|
||||||
server_cipher: Cipher,
|
|
||||||
device_map: Arc<Mutex<(u16, HashMap<Ipv4Addr, PeerDeviceInfo>)>>,
|
|
||||||
compressor: Compressor,
|
|
||||||
device_stop: DeviceStop,
|
|
||||||
allow_wire_guard: bool,
|
|
||||||
) -> anyhow::Result<()> {
|
|
||||||
let poll = Poll::new()?;
|
|
||||||
let waker = Arc::new(Waker::new(poll.registry(), STOP)?);
|
|
||||||
let _waker = waker.clone();
|
|
||||||
let worker = {
|
|
||||||
stop_manager.add_listener("tun_device".into(), move || {
|
|
||||||
if let Err(e) = waker.wake() {
|
|
||||||
log::warn!("{:?}", e);
|
|
||||||
}
|
|
||||||
})?
|
|
||||||
};
|
|
||||||
let worker_cell = Arc::new(AtomicCell::new(Some(worker)));
|
|
||||||
let _worker_cell = worker_cell.clone();
|
|
||||||
device_stop.set_stop_fn(move || {
|
|
||||||
if let Some(worker) = _worker_cell.take() {
|
|
||||||
worker.stop_self()
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if let Err(e) = start_simple0(
|
|
||||||
poll,
|
|
||||||
context,
|
|
||||||
device,
|
|
||||||
current_device,
|
|
||||||
ip_route,
|
|
||||||
#[cfg(feature = "ip_proxy")]
|
|
||||||
ip_proxy_map,
|
|
||||||
client_cipher,
|
|
||||||
server_cipher,
|
|
||||||
device_map,
|
|
||||||
compressor,
|
|
||||||
allow_wire_guard,
|
|
||||||
) {
|
|
||||||
log::error!("{:?}", e);
|
|
||||||
};
|
|
||||||
device_stop.stopped();
|
|
||||||
if let Some(worker) = worker_cell.take() {
|
|
||||||
worker.stop_all();
|
|
||||||
}
|
|
||||||
drop(_waker);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn start_simple0(
|
|
||||||
mut poll: Poll,
|
|
||||||
context: &ChannelContext,
|
|
||||||
device: Arc<Device>,
|
|
||||||
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
|
|
||||||
ip_route: ExternalRoute,
|
|
||||||
#[cfg(feature = "ip_proxy")] ip_proxy_map: Option<IpProxyMap>,
|
|
||||||
client_cipher: Cipher,
|
|
||||||
server_cipher: Cipher,
|
|
||||||
device_map: Arc<Mutex<(u16, HashMap<Ipv4Addr, PeerDeviceInfo>)>>,
|
|
||||||
compressor: Compressor,
|
|
||||||
allow_wire_guard: bool,
|
|
||||||
) -> anyhow::Result<()> {
|
|
||||||
let mut buf = [0; BUFFER_SIZE];
|
|
||||||
let mut extend = [0; BUFFER_SIZE];
|
|
||||||
let fd = device.as_tun_fd();
|
|
||||||
fd.set_nonblock()?;
|
|
||||||
SourceFd(&fd.as_raw_fd()).register(poll.registry(), FD, Interest::READABLE)?;
|
|
||||||
let mut events = Events::with_capacity(4);
|
|
||||||
#[cfg(not(target_os = "macos"))]
|
|
||||||
let start = 12;
|
|
||||||
#[cfg(target_os = "macos")]
|
|
||||||
let start = 12 - 4;
|
|
||||||
loop {
|
|
||||||
if let Err(e) = poll.poll(&mut events, None) {
|
|
||||||
crate::ignore_io_interrupted(e)?;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
for event in events.iter() {
|
|
||||||
if event.token() == STOP {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
let mut retries = 0;
|
|
||||||
loop {
|
|
||||||
let len = match fd.read(&mut buf[start..]) {
|
|
||||||
Ok(len) => len + start,
|
|
||||||
Err(e) => {
|
|
||||||
if e.kind() == io::ErrorKind::WouldBlock {
|
|
||||||
retries += 1;
|
|
||||||
if retries < 8 {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
Err(e)?
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// buf是重复利用的,需要重置头部
|
|
||||||
buf[..12].fill(0);
|
|
||||||
match crate::handle::tun_tap::tun_handler::handle(
|
|
||||||
context,
|
|
||||||
&mut buf,
|
|
||||||
len,
|
|
||||||
&mut extend,
|
|
||||||
&device,
|
|
||||||
current_device.load(),
|
|
||||||
&ip_route,
|
|
||||||
#[cfg(feature = "ip_proxy")]
|
|
||||||
&ip_proxy_map,
|
|
||||||
&client_cipher,
|
|
||||||
&server_cipher,
|
|
||||||
&device_map,
|
|
||||||
&compressor,
|
|
||||||
allow_wire_guard,
|
|
||||||
) {
|
|
||||||
Ok(_) => {}
|
|
||||||
Err(e) => {
|
|
||||||
log::warn!("{:?}", e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -66,11 +66,7 @@ pub fn start_port_mapping(
|
|||||||
if vec.is_empty() {
|
if vec.is_empty() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
let runtime = tokio::runtime::Builder::new_multi_thread()
|
|
||||||
.enable_all()
|
|
||||||
.thread_name("portMapping")
|
|
||||||
.build()?;
|
|
||||||
runtime.block_on(start_port_mapping0(vec))?;
|
|
||||||
let (sender, receiver) = tokio::sync::oneshot::channel::<()>();
|
let (sender, receiver) = tokio::sync::oneshot::channel::<()>();
|
||||||
let worker = stop_manager.add_listener("portMapping".into(), move || {
|
let worker = stop_manager.add_listener("portMapping".into(), move || {
|
||||||
let _ = sender.send(());
|
let _ = sender.send(());
|
||||||
@@ -78,6 +74,11 @@ pub fn start_port_mapping(
|
|||||||
thread::Builder::new()
|
thread::Builder::new()
|
||||||
.name("portMapping".into())
|
.name("portMapping".into())
|
||||||
.spawn(move || {
|
.spawn(move || {
|
||||||
|
let runtime = tokio::runtime::Builder::new_multi_thread()
|
||||||
|
.enable_all()
|
||||||
|
.thread_name("portMapping")
|
||||||
|
.build().unwrap();
|
||||||
|
runtime.block_on(start_port_mapping0(vec)).unwrap();
|
||||||
runtime.block_on(async {
|
runtime.block_on(async {
|
||||||
let _ = receiver.await;
|
let _ = receiver.await;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,19 +1,17 @@
|
|||||||
use crate::{DeviceConfig, ErrorInfo, ErrorType, VntCallback};
|
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::net::Ipv4Addr;
|
use std::net::Ipv4Addr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tun::device::IFace;
|
use tun_rs::SyncDevice;
|
||||||
use tun::Device;
|
|
||||||
|
use crate::{DeviceConfig, ErrorInfo, ErrorType, VntCallback};
|
||||||
|
|
||||||
#[cfg(any(target_os = "windows", target_os = "linux"))]
|
#[cfg(any(target_os = "windows", target_os = "linux"))]
|
||||||
const DEFAULT_TUN_NAME: &str = "vnt-tun";
|
const DEFAULT_TUN_NAME: &str = "vnt-tun";
|
||||||
#[cfg(target_os = "windows")]
|
|
||||||
const DEFAULT_TAP_NAME: &str = "vnt-tap";
|
|
||||||
|
|
||||||
pub fn create_device<Call: VntCallback>(
|
pub fn create_device<Call: VntCallback>(
|
||||||
config: DeviceConfig,
|
config: DeviceConfig,
|
||||||
call: &Call,
|
call: &Call,
|
||||||
) -> Result<Arc<Device>, ErrorInfo> {
|
) -> Result<Arc<SyncDevice>, ErrorInfo> {
|
||||||
let device = match create_device0(&config) {
|
let device = match create_device0(&config) {
|
||||||
Ok(device) => device,
|
Ok(device) => device,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
@@ -23,30 +21,24 @@ pub fn create_device<Call: VntCallback>(
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if let Err(e) = device.set_ip(config.virtual_ip, config.virtual_netmask) {
|
#[cfg(windows)]
|
||||||
log::error!("LocalIpExists {:?}", e);
|
let index = device.if_index().unwrap();
|
||||||
return Err(ErrorInfo::new_msg(
|
#[cfg(unix)]
|
||||||
ErrorType::LocalIpExists,
|
let index = &device.name().unwrap();
|
||||||
format!("set_ip {:?}", e),
|
if let Err(e) = add_route(index, Ipv4Addr::BROADCAST, Ipv4Addr::BROADCAST) {
|
||||||
));
|
|
||||||
}
|
|
||||||
if let Err(e) = device.add_route(config.virtual_network, config.virtual_netmask, 1) {
|
|
||||||
log::warn!("添加默认路由失败 ={:?}", e);
|
|
||||||
}
|
|
||||||
if let Err(e) = device.add_route(Ipv4Addr::BROADCAST, Ipv4Addr::BROADCAST, 1) {
|
|
||||||
log::warn!("添加广播路由失败 ={:?}", e);
|
log::warn!("添加广播路由失败 ={:?}", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Err(e) = device.add_route(
|
if let Err(e) = add_route(
|
||||||
|
index,
|
||||||
Ipv4Addr::from([224, 0, 0, 0]),
|
Ipv4Addr::from([224, 0, 0, 0]),
|
||||||
Ipv4Addr::from([240, 0, 0, 0]),
|
Ipv4Addr::from([240, 0, 0, 0]),
|
||||||
1,
|
|
||||||
) {
|
) {
|
||||||
log::warn!("添加组播路由失败 ={:?}", e);
|
log::warn!("添加组播路由失败 ={:?}", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (dest, mask) in config.external_route {
|
for (dest, mask) in config.external_route {
|
||||||
if let Err(e) = device.add_route(dest, mask, 1) {
|
if let Err(e) = add_route(index, dest, mask) {
|
||||||
log::warn!("添加路由失败,请检查-i参数是否和现有路由冲突 ={:?}", e);
|
log::warn!("添加路由失败,请检查-i参数是否和现有路由冲突 ={:?}", e);
|
||||||
call.error(ErrorInfo::new_msg(
|
call.error(ErrorInfo::new_msg(
|
||||||
ErrorType::Warn,
|
ErrorType::Warn,
|
||||||
@@ -60,15 +52,34 @@ pub fn create_device<Call: VntCallback>(
|
|||||||
Ok(device)
|
Ok(device)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_device0(config: &DeviceConfig) -> io::Result<Arc<Device>> {
|
fn create_device0(config: &DeviceConfig) -> io::Result<Arc<SyncDevice>> {
|
||||||
|
let mut tun_builder = tun_rs::DeviceBuilder::default();
|
||||||
|
tun_builder = tun_builder.ipv4(config.virtual_ip, config.virtual_netmask, None);
|
||||||
|
|
||||||
|
match &config.device_name {
|
||||||
|
None => {
|
||||||
|
#[cfg(any(target_os = "windows", target_os = "linux"))]
|
||||||
|
{
|
||||||
|
tun_builder = tun_builder.name(DEFAULT_TUN_NAME);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(name) => {
|
||||||
|
tun_builder = tun_builder.name(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
let default_name: &str = if config.tap {
|
{
|
||||||
DEFAULT_TAP_NAME
|
let name = config
|
||||||
} else {
|
.device_name
|
||||||
DEFAULT_TUN_NAME
|
.clone()
|
||||||
};
|
.unwrap_or_else(|| DEFAULT_TUN_NAME.to_string());
|
||||||
|
_ = delete_adapter_info_from_reg(&name);
|
||||||
|
tun_builder = tun_builder.metric(0).ring_capacity(4 * 1024 * 1024);
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
let device = {
|
{
|
||||||
let device_name = config
|
let device_name = config
|
||||||
.device_name
|
.device_name
|
||||||
.clone()
|
.clone()
|
||||||
@@ -76,20 +87,10 @@ fn create_device0(config: &DeviceConfig) -> io::Result<Arc<Device>> {
|
|||||||
if &device_name == DEFAULT_TUN_NAME {
|
if &device_name == DEFAULT_TUN_NAME {
|
||||||
delete_device(DEFAULT_TUN_NAME);
|
delete_device(DEFAULT_TUN_NAME);
|
||||||
}
|
}
|
||||||
Arc::new(Device::new(Some(device_name))?)
|
}
|
||||||
};
|
|
||||||
#[cfg(target_os = "macos")]
|
let device = tun_builder.mtu(config.mtu as u16).build_sync()?;
|
||||||
let device = Arc::new(Device::new(config.device_name.clone())?);
|
Ok(Arc::new(device))
|
||||||
#[cfg(target_os = "windows")]
|
|
||||||
let device = Arc::new(Device::new(
|
|
||||||
config
|
|
||||||
.device_name
|
|
||||||
.clone()
|
|
||||||
.unwrap_or(default_name.to_string()),
|
|
||||||
config.tap,
|
|
||||||
)?);
|
|
||||||
device.set_mtu(config.mtu)?;
|
|
||||||
Ok(device)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
@@ -106,3 +107,135 @@ fn delete_device(name: &str) {
|
|||||||
log::warn!("删除网卡失败:{:?}", delete_tun);
|
log::warn!("删除网卡失败:{:?}", delete_tun);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[cfg(windows)]
|
||||||
|
fn delete_adapter_info_from_reg(dev_name: &str) -> std::io::Result<()> {
|
||||||
|
use std::collections::HashSet;
|
||||||
|
use winreg::{enums::HKEY_LOCAL_MACHINE, enums::KEY_ALL_ACCESS, RegKey};
|
||||||
|
let hklm = RegKey::predef(HKEY_LOCAL_MACHINE);
|
||||||
|
let profiles_key = hklm.open_subkey_with_flags(
|
||||||
|
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkList\\Profiles",
|
||||||
|
KEY_ALL_ACCESS,
|
||||||
|
)?;
|
||||||
|
let mut profile_guid_set = HashSet::new();
|
||||||
|
for sub_key_name in profiles_key.enum_keys().filter_map(Result::ok) {
|
||||||
|
let sub_key = profiles_key.open_subkey(&sub_key_name)?;
|
||||||
|
match sub_key.get_value::<String, _>("Description") {
|
||||||
|
Ok(profile_name) => {
|
||||||
|
if dev_name == profile_name {
|
||||||
|
match profiles_key.delete_subkey_all(&sub_key_name) {
|
||||||
|
Ok(_) => {
|
||||||
|
log::info!("deleted Profiles sub_key: {}", sub_key_name);
|
||||||
|
profile_guid_set.insert(sub_key_name);
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
log::warn!("Failed to delete Profiles sub_key {}: {}", sub_key_name, e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => log::warn!(
|
||||||
|
"Failed to read Description for sub_key {}: {}",
|
||||||
|
sub_key_name,
|
||||||
|
e
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let unmanaged_key = hklm.open_subkey_with_flags(
|
||||||
|
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkList\\Signatures\\Unmanaged",
|
||||||
|
KEY_ALL_ACCESS,
|
||||||
|
)?;
|
||||||
|
for sub_key_name in unmanaged_key.enum_keys().filter_map(Result::ok) {
|
||||||
|
let sub_key = unmanaged_key.open_subkey(&sub_key_name)?;
|
||||||
|
match sub_key.get_value::<String, _>("ProfileGuid") {
|
||||||
|
Ok(profile_guid) => {
|
||||||
|
if profile_guid_set.contains(&profile_guid) {
|
||||||
|
match unmanaged_key.delete_subkey_all(&sub_key_name) {
|
||||||
|
Ok(_) => log::info!("deleted Unmanaged sub_key: {}", sub_key_name),
|
||||||
|
Err(e) => {
|
||||||
|
log::warn!("Failed to delete Unmanaged sub_key {}: {}", sub_key_name, e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => log::warn!(
|
||||||
|
"Failed to read Description for sub_key {}: {}",
|
||||||
|
sub_key_name,
|
||||||
|
e
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
pub fn add_route(index: u32, dest: Ipv4Addr, netmask: Ipv4Addr) -> io::Result<()> {
|
||||||
|
let cmd = format!(
|
||||||
|
"route add {:?} mask {:?} {:?} metric {} if {}",
|
||||||
|
dest,
|
||||||
|
netmask,
|
||||||
|
Ipv4Addr::UNSPECIFIED,
|
||||||
|
1,
|
||||||
|
index
|
||||||
|
);
|
||||||
|
exe_cmd(&cmd)
|
||||||
|
}
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
pub fn exe_cmd(cmd: &str) -> io::Result<()> {
|
||||||
|
use std::os::windows::process::CommandExt;
|
||||||
|
|
||||||
|
println!("exe cmd: {}", cmd);
|
||||||
|
let out = std::process::Command::new("cmd")
|
||||||
|
.creation_flags(windows_sys::Win32::System::Threading::CREATE_NO_WINDOW)
|
||||||
|
.arg("/C")
|
||||||
|
.arg(&cmd)
|
||||||
|
.output()?;
|
||||||
|
if !out.status.success() {
|
||||||
|
return Err(io::Error::new(
|
||||||
|
io::ErrorKind::Other,
|
||||||
|
format!("cmd={},out={:?}", cmd, String::from_utf8(out.stderr)),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
pub fn add_route(name: &str, address: Ipv4Addr, netmask: Ipv4Addr) -> io::Result<()> {
|
||||||
|
let cmd = format!(
|
||||||
|
"route -n add {} -netmask {} -interface {}",
|
||||||
|
address, netmask, name
|
||||||
|
);
|
||||||
|
exe_cmd(&cmd)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
pub fn add_route(name: &str, address: Ipv4Addr, netmask: Ipv4Addr) -> io::Result<()> {
|
||||||
|
let cmd = if netmask.is_broadcast() {
|
||||||
|
format!("route add -host {:?} {}", address, name)
|
||||||
|
} else {
|
||||||
|
format!(
|
||||||
|
"route add -net {}/{} {}",
|
||||||
|
address,
|
||||||
|
u32::from(netmask).count_ones(),
|
||||||
|
name
|
||||||
|
)
|
||||||
|
};
|
||||||
|
exe_cmd(&cmd)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
#[cfg(any(target_os = "macos", target_os = "linux"))]
|
||||||
|
pub fn exe_cmd(cmd: &str) -> io::Result<std::process::Output> {
|
||||||
|
use std::process::Command;
|
||||||
|
println!("exe cmd: {}", cmd);
|
||||||
|
let out = Command::new("sh")
|
||||||
|
.arg("-c")
|
||||||
|
.arg(cmd)
|
||||||
|
.output()
|
||||||
|
.expect("sh exec error!");
|
||||||
|
if !out.status.success() {
|
||||||
|
return Err(io::Error::new(
|
||||||
|
io::ErrorKind::Other,
|
||||||
|
format!("cmd={},out={:?}", cmd, out),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
Ok(out)
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,12 +3,6 @@ use std::io;
|
|||||||
use std::net::Ipv4Addr;
|
use std::net::Ipv4Addr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crossbeam_utils::atomic::AtomicCell;
|
|
||||||
use parking_lot::Mutex;
|
|
||||||
|
|
||||||
use tun::device::IFace;
|
|
||||||
use tun::Device;
|
|
||||||
|
|
||||||
use crate::channel::context::ChannelContext;
|
use crate::channel::context::ChannelContext;
|
||||||
use crate::cipher::Cipher;
|
use crate::cipher::Cipher;
|
||||||
use crate::compression::Compressor;
|
use crate::compression::Compressor;
|
||||||
@@ -19,15 +13,18 @@ use crate::handle::{CurrentDeviceInfo, PeerDeviceInfo};
|
|||||||
use crate::ip_proxy::IpProxyMap;
|
use crate::ip_proxy::IpProxyMap;
|
||||||
use crate::tun_tap_device::vnt_device::DeviceWrite;
|
use crate::tun_tap_device::vnt_device::DeviceWrite;
|
||||||
use crate::util::StopManager;
|
use crate::util::StopManager;
|
||||||
|
use crossbeam_utils::atomic::AtomicCell;
|
||||||
|
use parking_lot::Mutex;
|
||||||
|
use tun_rs::SyncDevice;
|
||||||
|
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
pub struct DeviceAdapter {
|
pub struct DeviceAdapter {
|
||||||
tun: Arc<Mutex<Option<Arc<Device>>>>,
|
tun: Arc<Mutex<Option<Arc<SyncDevice>>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DeviceAdapter {
|
impl DeviceAdapter {
|
||||||
pub fn insert(&self, device: Arc<Device>) {
|
pub fn insert(&self, device: Arc<SyncDevice>) {
|
||||||
let r = self.tun.lock().replace(device);
|
let r = self.tun.lock().replace(device);
|
||||||
assert!(r.is_none());
|
assert!(r.is_none());
|
||||||
}
|
}
|
||||||
@@ -41,7 +38,7 @@ impl DeviceWrite for DeviceAdapter {
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
||||||
if let Some(tun) = self.tun.lock().as_ref() {
|
if let Some(tun) = self.tun.lock().as_ref() {
|
||||||
tun.write(buf)
|
tun.send(buf)
|
||||||
} else {
|
} else {
|
||||||
Err(io::Error::new(io::ErrorKind::NotFound, "not tun device"))
|
Err(io::Error::new(io::ErrorKind::NotFound, "not tun device"))
|
||||||
}
|
}
|
||||||
@@ -119,7 +116,7 @@ impl TunDeviceHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// 要保证先stop 再start
|
/// 要保证先stop 再start
|
||||||
pub fn start(&self, device: Arc<Device>, allow_wire_guard: bool) -> io::Result<()> {
|
pub fn start(&self, device: Arc<SyncDevice>, allow_wire_guard: bool) -> io::Result<()> {
|
||||||
self.device_adapter.insert(device.clone());
|
self.device_adapter.insert(device.clone());
|
||||||
let device_stop = DeviceStop::default();
|
let device_stop = DeviceStop::default();
|
||||||
let s = self.device_stop.lock().replace(device_stop.clone());
|
let s = self.device_stop.lock().replace(device_stop.clone());
|
||||||
|
|||||||
+139
-12
@@ -1,3 +1,8 @@
|
|||||||
|
use crate::channel::socket::LocalInterface;
|
||||||
|
use anyhow::Context;
|
||||||
|
use dns_parser::{Builder, Packet, QueryClass, QueryType, RData, ResponseCode};
|
||||||
|
use http_req::request::{RedirectPolicy, Request};
|
||||||
|
use http_req::uri::Uri;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, ToSocketAddrs, UdpSocket};
|
use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, ToSocketAddrs, UdpSocket};
|
||||||
@@ -5,10 +10,6 @@ use std::str::FromStr;
|
|||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use std::{io, thread};
|
use std::{io, thread};
|
||||||
|
|
||||||
use crate::channel::socket::LocalInterface;
|
|
||||||
use anyhow::Context;
|
|
||||||
use dns_parser::{Builder, Packet, QueryClass, QueryType, RData, ResponseCode};
|
|
||||||
|
|
||||||
thread_local! {
|
thread_local! {
|
||||||
static HISTORY: RefCell<HashMap<SocketAddr,usize>> = RefCell::new(HashMap::new());
|
static HISTORY: RefCell<HashMap<SocketAddr,usize>> = RefCell::new(HashMap::new());
|
||||||
}
|
}
|
||||||
@@ -82,21 +83,47 @@ pub fn dns_query_all(
|
|||||||
mut name_servers: Vec<String>,
|
mut name_servers: Vec<String>,
|
||||||
default_interface: &LocalInterface,
|
default_interface: &LocalInterface,
|
||||||
) -> anyhow::Result<Vec<SocketAddr>> {
|
) -> anyhow::Result<Vec<SocketAddr>> {
|
||||||
match SocketAddr::from_str(domain) {
|
let mut current_domain = domain.to_string(); // 引入可变变量存储当前域名
|
||||||
|
match SocketAddr::from_str(¤t_domain) {
|
||||||
Ok(addr) => Ok(vec![addr]),
|
Ok(addr) => Ok(vec![addr]),
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
let txt_domain = domain
|
// 重定向判断 http:
|
||||||
|
let current_domain_lower = current_domain.to_lowercase();
|
||||||
|
let redirect_domain = current_domain_lower
|
||||||
|
.strip_prefix("http:")
|
||||||
|
.or_else(|| current_domain_lower.strip_prefix("https:"))
|
||||||
|
.map(|v| v.to_string());
|
||||||
|
|
||||||
|
// 执行重定向检查
|
||||||
|
if let Some(stripped) = redirect_domain {
|
||||||
|
if let Some(redirected_url) = check_for_redirect(&stripped)? {
|
||||||
|
// 去掉 URL 开头的协议部分
|
||||||
|
let final_domain = remove_http_prefix(&redirected_url);
|
||||||
|
println!("Server Address: {}", final_domain);
|
||||||
|
|
||||||
|
// 检查是否为 IP 和端口组合
|
||||||
|
if let Ok(socket_addr) = SocketAddr::from_str(&final_domain) {
|
||||||
|
// 如果是 IP 和端口格式,直接返回结果
|
||||||
|
return Ok(vec![socket_addr]);
|
||||||
|
} else {
|
||||||
|
// 如果不是 IP 和端口格式,则更新为重定向地址
|
||||||
|
current_domain = final_domain;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let txt_domain = current_domain
|
||||||
.to_lowercase()
|
.to_lowercase()
|
||||||
.strip_prefix("txt:")
|
.strip_prefix("txt:")
|
||||||
.map(|v| v.to_string());
|
.map(|v| v.to_string());
|
||||||
if name_servers.is_empty() {
|
if name_servers.is_empty() {
|
||||||
if txt_domain.is_some() {
|
if txt_domain.is_some() {
|
||||||
name_servers.push("223.5.5.5:53".into());
|
name_servers.push("223.5.5.5:53".into());
|
||||||
|
name_servers.push("119.29.29.29:53".into());
|
||||||
name_servers.push("114.114.114.114:53".into());
|
name_servers.push("114.114.114.114:53".into());
|
||||||
} else {
|
} else {
|
||||||
return Ok(domain
|
return Ok(current_domain
|
||||||
.to_socket_addrs()
|
.to_socket_addrs()
|
||||||
.with_context(|| format!("DNS query failed {:?}", domain))?
|
.with_context(|| format!("DNS query failed {:?}", current_domain))?
|
||||||
.collect());
|
.collect());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -107,6 +134,7 @@ pub fn dns_query_all(
|
|||||||
match txt_dns(domain, name_server, default_interface) {
|
match txt_dns(domain, name_server, default_interface) {
|
||||||
Ok(addr) => {
|
Ok(addr) => {
|
||||||
if !addr.is_empty() {
|
if !addr.is_empty() {
|
||||||
|
println!("TXT: {:?}", addr);
|
||||||
return Ok(addr);
|
return Ok(addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -120,12 +148,13 @@ pub fn dns_query_all(
|
|||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let end_index = domain
|
|
||||||
|
let end_index = current_domain
|
||||||
.rfind(':')
|
.rfind(':')
|
||||||
.with_context(|| format!("{:?} not port", domain))?;
|
.with_context(|| format!("{:?} not port", current_domain))?;
|
||||||
let host = &domain[..end_index];
|
let host = &domain[..end_index];
|
||||||
let port = u16::from_str(&domain[end_index + 1..])
|
let port = u16::from_str(&domain[end_index + 1..])
|
||||||
.with_context(|| format!("{:?} not port", domain))?;
|
.with_context(|| format!("{:?} not port", current_domain))?;
|
||||||
let th1 = {
|
let th1 = {
|
||||||
let host = host.to_string();
|
let host = host.to_string();
|
||||||
let name_server = name_server.clone();
|
let name_server = name_server.clone();
|
||||||
@@ -174,12 +203,110 @@ pub fn dns_query_all(
|
|||||||
if let Some(e) = err {
|
if let Some(e) = err {
|
||||||
Err(e)
|
Err(e)
|
||||||
} else {
|
} else {
|
||||||
Err(anyhow::anyhow!("DNS query failed {:?}", domain))
|
Err(anyhow::anyhow!("DNS query failed {:?}", current_domain))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_host_port(addr: &str) -> bool {
|
||||||
|
// 处理 IPv6 地址(格式为 [::1]:8080)
|
||||||
|
if addr.starts_with('[') {
|
||||||
|
if let Some(idx) = addr.rfind(']') {
|
||||||
|
if let Some(port_idx) = addr[idx + 1..].find(':') {
|
||||||
|
let port = &addr[idx + 1 + port_idx + 1..]; // 提取端口部分
|
||||||
|
return !port.is_empty() && port.chars().all(|c| c.is_numeric());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 处理 IPv4 和普通域名(格式为 example.com:443 或 192.168.1.1:8080)
|
||||||
|
if let Some((_host, port)) = addr.rsplit_once(':') {
|
||||||
|
return !port.is_empty() && port.chars().all(|c| c.is_numeric());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_for_redirect(domain: &String) -> anyhow::Result<Option<String>> {
|
||||||
|
// 确保域名有 http:// 或 https:// 前缀
|
||||||
|
let mut url = if domain.starts_with("http://") || domain.starts_with("https://") {
|
||||||
|
domain.clone()
|
||||||
|
} else {
|
||||||
|
format!("http://{}", domain)
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut count = 0; // 重定向次数计数器
|
||||||
|
let mut last_redirect_url: Option<String> = None; // 记录最后一个重定向的 URL
|
||||||
|
|
||||||
|
loop {
|
||||||
|
count += 1;
|
||||||
|
if count > 3 {
|
||||||
|
println!("重定向次数超过 3 次,跳过");
|
||||||
|
return Ok(last_redirect_url);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解析 URL
|
||||||
|
let uri = match Uri::try_from(url.as_str()) {
|
||||||
|
Ok(u) => u,
|
||||||
|
Err(e) => {
|
||||||
|
println!("解析地址失败: {}", e);
|
||||||
|
return Ok(last_redirect_url);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut response_body = Vec::new();
|
||||||
|
|
||||||
|
// 发送 HTTP 请求
|
||||||
|
let response = match Request::new(&uri)
|
||||||
|
.timeout(Duration::from_secs(10))
|
||||||
|
.redirect_policy(RedirectPolicy::Limit(0))
|
||||||
|
.send(&mut response_body)
|
||||||
|
{
|
||||||
|
Ok(resp) => {
|
||||||
|
println!("HTTP Status Code: {}", resp.status_code());
|
||||||
|
resp
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
return Ok(last_redirect_url);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let body_str = String::from_utf8_lossy(&response_body);
|
||||||
|
let cleaned_body = body_str.replace('\n', "").replace('\r', "");
|
||||||
|
println!("Response Body: {}", cleaned_body);
|
||||||
|
// 处理 3XX 重定向
|
||||||
|
if response.status_code().is_redirect() {
|
||||||
|
if let Some(location) = response.headers().get("Location") {
|
||||||
|
url = location.to_string().trim_end_matches('/').to_string();
|
||||||
|
last_redirect_url = Some(url.clone()); // 更新最后的重定向地址
|
||||||
|
println!("Location: {}", url);
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
return Ok(last_redirect_url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 处理 200 响应
|
||||||
|
else if response.status_code().is_success() {
|
||||||
|
for line in body_str.lines() {
|
||||||
|
let trimmed = line.trim();
|
||||||
|
if parse_host_port(trimmed) {
|
||||||
|
println!("text: {}", trimmed);
|
||||||
|
return Ok(Some(trimmed.to_string()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Ok(last_redirect_url);
|
||||||
|
}
|
||||||
|
return Ok(last_redirect_url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 去掉 http:// 或 https:// 前缀
|
||||||
|
fn remove_http_prefix(url: &str) -> String {
|
||||||
|
url.trim_start_matches("http://")
|
||||||
|
.trim_start_matches("https://")
|
||||||
|
.to_string()
|
||||||
|
}
|
||||||
|
|
||||||
fn query<'a>(
|
fn query<'a>(
|
||||||
udp: &UdpSocket,
|
udp: &UdpSocket,
|
||||||
domain: &str,
|
domain: &str,
|
||||||
|
|||||||
@@ -1,34 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "tun"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
libc = "0.2.153"
|
|
||||||
|
|
||||||
log = { version = "0.4.20", features = [] }
|
|
||||||
rand = "0.8.5"
|
|
||||||
sha2 = { version = "0.10.6", features = ["oid"] }
|
|
||||||
|
|
||||||
[target.'cfg(any(target_os = "linux", target_os = "macos"))'.dependencies]
|
|
||||||
ioctl = { version = "0.8", package = "ioctl-sys" }
|
|
||||||
|
|
||||||
[target.'cfg(target_os = "windows")'.dependencies]
|
|
||||||
libloading = "0.8.0"
|
|
||||||
widestring = "1.0.2"
|
|
||||||
winapi = { version = "0.3", features = [
|
|
||||||
"errhandlingapi",
|
|
||||||
"libloaderapi",
|
|
||||||
"combaseapi",
|
|
||||||
"ioapiset",
|
|
||||||
"winioctl",
|
|
||||||
"setupapi",
|
|
||||||
"synchapi",
|
|
||||||
"netioapi",
|
|
||||||
"fileapi", "handleapi", "winerror", "minwindef", "ifdef", "basetsd", "winnt", "winreg", "winbase", "minwinbase",
|
|
||||||
"impl-default"
|
|
||||||
] }
|
|
||||||
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
use crate::device::IFace;
|
|
||||||
use crate::Fd;
|
|
||||||
use std::io;
|
|
||||||
use std::net::Ipv4Addr;
|
|
||||||
use std::os::fd::RawFd;
|
|
||||||
|
|
||||||
pub struct Device {
|
|
||||||
fd: Fd,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Device {
|
|
||||||
pub fn new(fd: RawFd) -> io::Result<Self> {
|
|
||||||
Ok(Self { fd: Fd::new(fd)? })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl Device {
|
|
||||||
pub fn as_tun_fd(&self) -> &Fd {
|
|
||||||
&self.fd
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl IFace for Device {
|
|
||||||
fn version(&self) -> io::Result<String> {
|
|
||||||
Ok(String::new())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn name(&self) -> io::Result<String> {
|
|
||||||
Ok(String::new())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn shutdown(&self) -> io::Result<()> {
|
|
||||||
Err(io::Error::from(io::ErrorKind::Unsupported))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_ip(&self, _address: Ipv4Addr, _mask: Ipv4Addr) -> io::Result<()> {
|
|
||||||
Err(io::Error::from(io::ErrorKind::Unsupported))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn mtu(&self) -> io::Result<u32> {
|
|
||||||
Err(io::Error::from(io::ErrorKind::Unsupported))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_mtu(&self, _value: u32) -> io::Result<()> {
|
|
||||||
Err(io::Error::from(io::ErrorKind::Unsupported))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn add_route(&self, _dest: Ipv4Addr, _netmask: Ipv4Addr, _metric: u16) -> io::Result<()> {
|
|
||||||
Err(io::Error::from(io::ErrorKind::Unsupported))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn delete_route(&self, _dest: Ipv4Addr, _netmask: Ipv4Addr) -> io::Result<()> {
|
|
||||||
Err(io::Error::from(io::ErrorKind::Unsupported))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
|
|
||||||
self.fd.read(buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
|
||||||
self.fd.write(buf)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
use io::Result;
|
|
||||||
use std::io;
|
|
||||||
use std::net::Ipv4Addr;
|
|
||||||
|
|
||||||
pub trait IFace {
|
|
||||||
fn version(&self) -> Result<String>;
|
|
||||||
/// Get the device name.
|
|
||||||
fn name(&self) -> Result<String>;
|
|
||||||
|
|
||||||
fn shutdown(&self) -> Result<()>;
|
|
||||||
|
|
||||||
fn set_ip(&self, address: Ipv4Addr, mask: Ipv4Addr) -> Result<()>;
|
|
||||||
|
|
||||||
/// Get the MTU.
|
|
||||||
fn mtu(&self) -> Result<u32>;
|
|
||||||
|
|
||||||
/// Set the MTU.
|
|
||||||
fn set_mtu(&self, value: u32) -> Result<()>;
|
|
||||||
fn add_route(&self, dest: Ipv4Addr, netmask: Ipv4Addr, metric: u16) -> Result<()>;
|
|
||||||
fn delete_route(&self, dest: Ipv4Addr, netmask: Ipv4Addr) -> Result<()>;
|
|
||||||
|
|
||||||
fn read(&self, buf: &mut [u8]) -> Result<usize>;
|
|
||||||
fn write(&self, buf: &[u8]) -> Result<usize>;
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
/// 参考
|
|
||||||
/// https://github.com/meh/rust-tun
|
|
||||||
/// https://github.com/Tazdevil971/tap-windows
|
|
||||||
/// https://github.com/nulldotblack/wintun
|
|
||||||
pub mod device;
|
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
mod linux;
|
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
pub use linux::Device;
|
|
||||||
|
|
||||||
#[cfg(target_os = "android")]
|
|
||||||
mod android;
|
|
||||||
#[cfg(target_os = "android")]
|
|
||||||
pub use android::Device;
|
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
|
||||||
mod macos;
|
|
||||||
#[cfg(target_os = "macos")]
|
|
||||||
pub use macos::Device;
|
|
||||||
|
|
||||||
#[cfg(unix)]
|
|
||||||
mod unix;
|
|
||||||
#[cfg(unix)]
|
|
||||||
pub use unix::Fd;
|
|
||||||
#[cfg(windows)]
|
|
||||||
mod windows;
|
|
||||||
|
|
||||||
#[cfg(windows)]
|
|
||||||
pub use windows::Device;
|
|
||||||
|
|
||||||
#[cfg(windows)]
|
|
||||||
mod packet;
|
|
||||||
@@ -1,281 +0,0 @@
|
|||||||
#![allow(dead_code)]
|
|
||||||
use std::ffi::{CStr, CString};
|
|
||||||
use std::net::Ipv4Addr;
|
|
||||||
use std::os::fd::AsRawFd;
|
|
||||||
use std::{io, mem, ptr};
|
|
||||||
|
|
||||||
use libc::{
|
|
||||||
c_char, c_short, ifreq, AF_INET, IFF_MULTI_QUEUE, IFF_NO_PI, IFF_RUNNING, IFF_TUN, IFF_UP,
|
|
||||||
IFNAMSIZ, O_RDWR, SOCK_DGRAM,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::device::IFace;
|
|
||||||
use crate::linux::route;
|
|
||||||
use crate::linux::sys::*;
|
|
||||||
use crate::unix::{exe_cmd, Fd, SockAddr};
|
|
||||||
|
|
||||||
pub struct Device {
|
|
||||||
name: String,
|
|
||||||
ctl: Fd,
|
|
||||||
tun: Fd,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Device {
|
|
||||||
pub fn new(name: Option<String>) -> io::Result<Self> {
|
|
||||||
let device = unsafe {
|
|
||||||
let dev = match name {
|
|
||||||
Some(name) => {
|
|
||||||
let name =
|
|
||||||
CString::new(name).map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
|
|
||||||
|
|
||||||
if name.as_bytes_with_nul().len() > IFNAMSIZ {
|
|
||||||
return Err(io::Error::new(io::ErrorKind::InvalidInput, "name too long"));
|
|
||||||
}
|
|
||||||
|
|
||||||
Some(name)
|
|
||||||
}
|
|
||||||
|
|
||||||
None => None,
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut req: ifreq = mem::zeroed();
|
|
||||||
|
|
||||||
if let Some(dev) = dev.as_ref() {
|
|
||||||
ptr::copy_nonoverlapping(
|
|
||||||
dev.as_ptr() as *const c_char,
|
|
||||||
req.ifr_name.as_mut_ptr(),
|
|
||||||
dev.as_bytes().len(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
let device_type: c_short = IFF_TUN as c_short; //if tap { IFF_TAP } else { IFF_TUN } as c_short;
|
|
||||||
|
|
||||||
let queues_num = 1;
|
|
||||||
|
|
||||||
let iff_no_pi = IFF_NO_PI as c_short;
|
|
||||||
let iff_multi_queue = IFF_MULTI_QUEUE as c_short;
|
|
||||||
let packet_information = false;
|
|
||||||
req.ifr_ifru.ifru_flags = device_type
|
|
||||||
| if packet_information { 0 } else { iff_no_pi }
|
|
||||||
| if queues_num > 1 { iff_multi_queue } else { 0 };
|
|
||||||
|
|
||||||
let tun = Fd::new(libc::open(b"/dev/net/tun\0".as_ptr() as *const _, O_RDWR))
|
|
||||||
.map_err(|_| io::Error::last_os_error())?;
|
|
||||||
|
|
||||||
if tunsetiff(tun.0, &mut req as *mut _ as *mut _) < 0 {
|
|
||||||
return Err(io::Error::last_os_error());
|
|
||||||
}
|
|
||||||
|
|
||||||
let ctl = Fd::new(libc::socket(AF_INET, SOCK_DGRAM, 0))?;
|
|
||||||
|
|
||||||
let name = CStr::from_ptr(req.ifr_name.as_ptr())
|
|
||||||
.to_string_lossy()
|
|
||||||
.to_string();
|
|
||||||
let set_txqueuelen = format!("ifconfig {} txqueuelen 1000", name);
|
|
||||||
if let Err(e) = exe_cmd(&set_txqueuelen) {
|
|
||||||
log::warn!("{:?}", e);
|
|
||||||
}
|
|
||||||
Device { name, tun, ctl }
|
|
||||||
};
|
|
||||||
device.enabled(true)?;
|
|
||||||
Ok(device)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Device {
|
|
||||||
fn enabled(&self, value: bool) -> io::Result<()> {
|
|
||||||
unsafe {
|
|
||||||
let mut req = self.request();
|
|
||||||
|
|
||||||
if siocgifflags(self.ctl.as_raw_fd(), &mut req) < 0 {
|
|
||||||
return Err(io::Error::last_os_error());
|
|
||||||
}
|
|
||||||
|
|
||||||
if value {
|
|
||||||
req.ifr_ifru.ifru_flags |= (IFF_UP | IFF_RUNNING) as c_short;
|
|
||||||
} else {
|
|
||||||
req.ifr_ifru.ifru_flags &= !(IFF_UP as c_short);
|
|
||||||
}
|
|
||||||
|
|
||||||
if siocsifflags(self.ctl.as_raw_fd(), &req) < 0 {
|
|
||||||
return Err(io::Error::last_os_error());
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unsafe fn request(&self) -> ifreq {
|
|
||||||
let mut req: ifreq = mem::zeroed();
|
|
||||||
ptr::copy_nonoverlapping(
|
|
||||||
self.name.as_ptr() as *const c_char,
|
|
||||||
req.ifr_name.as_mut_ptr(),
|
|
||||||
self.name.len(),
|
|
||||||
);
|
|
||||||
req
|
|
||||||
}
|
|
||||||
fn address(&self) -> io::Result<Ipv4Addr> {
|
|
||||||
unsafe {
|
|
||||||
let mut req = self.request();
|
|
||||||
|
|
||||||
if siocgifaddr(self.ctl.as_raw_fd(), &mut req) < 0 {
|
|
||||||
return Err(io::Error::last_os_error().into());
|
|
||||||
}
|
|
||||||
|
|
||||||
SockAddr::new(&req.ifr_ifru.ifru_addr).map(Into::into)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_address(&self, value: Ipv4Addr) -> io::Result<()> {
|
|
||||||
unsafe {
|
|
||||||
let mut req = self.request();
|
|
||||||
req.ifr_ifru.ifru_addr = SockAddr::from(value).into();
|
|
||||||
|
|
||||||
if siocsifaddr(self.ctl.as_raw_fd(), &req) < 0 {
|
|
||||||
return Err(io::Error::last_os_error());
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn destination(&self) -> io::Result<Ipv4Addr> {
|
|
||||||
unsafe {
|
|
||||||
let mut req = self.request();
|
|
||||||
|
|
||||||
if siocgifdstaddr(self.ctl.as_raw_fd(), &mut req) < 0 {
|
|
||||||
return Err(io::Error::last_os_error());
|
|
||||||
}
|
|
||||||
|
|
||||||
SockAddr::new(&req.ifr_ifru.ifru_dstaddr).map(Into::into)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_destination(&self, value: Ipv4Addr) -> io::Result<()> {
|
|
||||||
unsafe {
|
|
||||||
let mut req = self.request();
|
|
||||||
req.ifr_ifru.ifru_dstaddr = SockAddr::from(value).into();
|
|
||||||
|
|
||||||
if siocsifdstaddr(self.ctl.as_raw_fd(), &req) < 0 {
|
|
||||||
return Err(io::Error::last_os_error());
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn broadcast(&self) -> io::Result<Ipv4Addr> {
|
|
||||||
unsafe {
|
|
||||||
let mut req = self.request();
|
|
||||||
|
|
||||||
if siocgifbrdaddr(self.ctl.as_raw_fd(), &mut req) < 0 {
|
|
||||||
return Err(io::Error::last_os_error());
|
|
||||||
}
|
|
||||||
|
|
||||||
SockAddr::new(&req.ifr_ifru.ifru_broadaddr).map(Into::into)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_broadcast(&self, value: Ipv4Addr) -> io::Result<()> {
|
|
||||||
unsafe {
|
|
||||||
let mut req = self.request();
|
|
||||||
req.ifr_ifru.ifru_broadaddr = SockAddr::from(value).into();
|
|
||||||
|
|
||||||
if siocsifbrdaddr(self.ctl.as_raw_fd(), &req) < 0 {
|
|
||||||
return Err(io::Error::last_os_error());
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn netmask(&self) -> io::Result<Ipv4Addr> {
|
|
||||||
unsafe {
|
|
||||||
let mut req = self.request();
|
|
||||||
|
|
||||||
if siocgifnetmask(self.ctl.as_raw_fd(), &mut req) < 0 {
|
|
||||||
return Err(io::Error::last_os_error());
|
|
||||||
}
|
|
||||||
|
|
||||||
SockAddr::new(&req.ifr_ifru.ifru_netmask).map(Into::into)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_netmask(&self, value: Ipv4Addr) -> io::Result<()> {
|
|
||||||
unsafe {
|
|
||||||
let mut req = self.request();
|
|
||||||
req.ifr_ifru.ifru_netmask = SockAddr::from(value).into();
|
|
||||||
|
|
||||||
if siocsifnetmask(self.ctl.as_raw_fd(), &req) < 0 {
|
|
||||||
return Err(io::Error::last_os_error());
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Device {
|
|
||||||
pub fn as_tun_fd(&self) -> &Fd {
|
|
||||||
&self.tun
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl IFace for Device {
|
|
||||||
fn version(&self) -> io::Result<String> {
|
|
||||||
Ok(String::new())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn name(&self) -> io::Result<String> {
|
|
||||||
Ok(self.name.clone())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn shutdown(&self) -> io::Result<()> {
|
|
||||||
exe_cmd(&format!("ip link delete {}", self.name))?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
fn set_ip(&self, address: Ipv4Addr, mask: Ipv4Addr) -> io::Result<()> {
|
|
||||||
self.set_address(address)?;
|
|
||||||
self.set_netmask(mask)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn mtu(&self) -> io::Result<u32> {
|
|
||||||
unsafe {
|
|
||||||
let mut req = self.request();
|
|
||||||
|
|
||||||
if siocgifmtu(self.ctl.as_raw_fd(), &mut req) < 0 {
|
|
||||||
return Err(io::Error::last_os_error());
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(req.ifr_ifru.ifru_mtu as u32)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_mtu(&self, value: u32) -> io::Result<()> {
|
|
||||||
unsafe {
|
|
||||||
let mut req = self.request();
|
|
||||||
req.ifr_ifru.ifru_mtu = value as _;
|
|
||||||
|
|
||||||
if siocsifmtu(self.ctl.as_raw_fd(), &req) < 0 {
|
|
||||||
return Err(io::Error::last_os_error());
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn add_route(&self, dest: Ipv4Addr, netmask: Ipv4Addr, _metric: u16) -> io::Result<()> {
|
|
||||||
route::add_route(&self.name, dest, netmask)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn delete_route(&self, dest: Ipv4Addr, netmask: Ipv4Addr) -> io::Result<()> {
|
|
||||||
route::del_route(&self.name, dest, netmask)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
|
|
||||||
self.tun.read(buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
|
||||||
self.tun.write(buf)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
mod device;
|
|
||||||
pub use device::Device;
|
|
||||||
mod route;
|
|
||||||
mod sys;
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
use std::io;
|
|
||||||
use std::net::Ipv4Addr;
|
|
||||||
|
|
||||||
use crate::unix::exe_cmd;
|
|
||||||
|
|
||||||
pub fn add_route(name: &str, address: Ipv4Addr, netmask: Ipv4Addr) -> io::Result<()> {
|
|
||||||
let cmd = if netmask.is_broadcast() {
|
|
||||||
format!("route add -host {:?} {}", address, name)
|
|
||||||
} else {
|
|
||||||
format!(
|
|
||||||
"route add -net {}/{} {}",
|
|
||||||
address,
|
|
||||||
u32::from(netmask).count_ones(),
|
|
||||||
name
|
|
||||||
)
|
|
||||||
};
|
|
||||||
exe_cmd(&cmd)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn del_route(name: &str, address: Ipv4Addr, netmask: Ipv4Addr) -> io::Result<()> {
|
|
||||||
let cmd = format!("ip route del {:?}/{:?} dev {}", address, netmask, name);
|
|
||||||
exe_cmd(&cmd)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
use ioctl::*;
|
|
||||||
use libc::{c_int, ifreq};
|
|
||||||
|
|
||||||
ioctl!(bad read siocgifflags with 0x8913; ifreq);
|
|
||||||
ioctl!(bad write siocsifflags with 0x8914; ifreq);
|
|
||||||
ioctl!(bad read siocgifaddr with 0x8915; ifreq);
|
|
||||||
ioctl!(bad write siocsifaddr with 0x8916; ifreq);
|
|
||||||
ioctl!(bad read siocgifdstaddr with 0x8917; ifreq);
|
|
||||||
ioctl!(bad write siocsifdstaddr with 0x8918; ifreq);
|
|
||||||
ioctl!(bad read siocgifbrdaddr with 0x8919; ifreq);
|
|
||||||
ioctl!(bad write siocsifbrdaddr with 0x891a; ifreq);
|
|
||||||
ioctl!(bad read siocgifnetmask with 0x891b; ifreq);
|
|
||||||
ioctl!(bad write siocsifnetmask with 0x891c; ifreq);
|
|
||||||
ioctl!(bad read siocgifmtu with 0x8921; ifreq);
|
|
||||||
ioctl!(bad write siocsifmtu with 0x8922; ifreq);
|
|
||||||
ioctl!(bad write siocsifname with 0x8923; ifreq);
|
|
||||||
|
|
||||||
ioctl!(write tunsetiff with b'T', 202; c_int);
|
|
||||||
ioctl!(write tunsetpersist with b'T', 203; c_int);
|
|
||||||
ioctl!(write tunsetowner with b'T', 204; c_int);
|
|
||||||
ioctl!(write tunsetgroup with b'T', 206; c_int);
|
|
||||||
@@ -1,297 +0,0 @@
|
|||||||
#![allow(dead_code)]
|
|
||||||
use std::ffi::{c_void, CStr};
|
|
||||||
use std::net::Ipv4Addr;
|
|
||||||
use std::os::fd::AsRawFd;
|
|
||||||
use std::{io, mem, ptr};
|
|
||||||
|
|
||||||
use libc::{
|
|
||||||
c_char, c_short, c_uint, sockaddr, socklen_t, AF_INET, AF_SYSTEM, AF_SYS_CONTROL, IFF_RUNNING,
|
|
||||||
IFF_UP, IFNAMSIZ, PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL, UTUN_OPT_IFNAME,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::device::IFace;
|
|
||||||
use crate::macos::route;
|
|
||||||
use crate::macos::sys::*;
|
|
||||||
use crate::unix::{Fd, SockAddr};
|
|
||||||
|
|
||||||
pub struct Device {
|
|
||||||
name: String,
|
|
||||||
ctl: Fd,
|
|
||||||
tun: Fd,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Device {
|
|
||||||
pub fn new(name: Option<String>) -> io::Result<Self> {
|
|
||||||
let id = if let Some(name) = name {
|
|
||||||
if name.len() > IFNAMSIZ {
|
|
||||||
return Err(io::Error::new(io::ErrorKind::InvalidInput, "name too long"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if !name.starts_with("utun") {
|
|
||||||
return Err(io::Error::new(io::ErrorKind::InvalidInput, "invalid name"));
|
|
||||||
}
|
|
||||||
|
|
||||||
name[4..]
|
|
||||||
.parse::<u32>()
|
|
||||||
.map_err(|e| io::Error::new(io::ErrorKind::Other, e))?
|
|
||||||
+ 1u32
|
|
||||||
} else {
|
|
||||||
0u32
|
|
||||||
};
|
|
||||||
let device = unsafe {
|
|
||||||
let tun = Fd::new(libc::socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL))?;
|
|
||||||
|
|
||||||
let mut info = ctl_info {
|
|
||||||
ctl_id: 0,
|
|
||||||
ctl_name: {
|
|
||||||
let mut buffer = [0; 96];
|
|
||||||
for (i, o) in UTUN_CONTROL_NAME.as_bytes().iter().zip(buffer.iter_mut()) {
|
|
||||||
*o = *i as _;
|
|
||||||
}
|
|
||||||
buffer
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
if ctliocginfo(tun.0, &mut info as *mut _ as *mut _) < 0 {
|
|
||||||
return Err(io::Error::last_os_error());
|
|
||||||
}
|
|
||||||
|
|
||||||
let addr = sockaddr_ctl {
|
|
||||||
sc_id: info.ctl_id,
|
|
||||||
sc_len: mem::size_of::<sockaddr_ctl>() as _,
|
|
||||||
sc_family: AF_SYSTEM as _,
|
|
||||||
ss_sysaddr: AF_SYS_CONTROL as _,
|
|
||||||
sc_unit: id as c_uint,
|
|
||||||
sc_reserved: [0; 5],
|
|
||||||
};
|
|
||||||
|
|
||||||
let address = &addr as *const sockaddr_ctl as *const sockaddr;
|
|
||||||
if libc::connect(tun.0, address, mem::size_of_val(&addr) as socklen_t) < 0 {
|
|
||||||
return Err(io::Error::last_os_error());
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut name = [0u8; 64];
|
|
||||||
let mut name_len: socklen_t = 64;
|
|
||||||
|
|
||||||
let optval = &mut name as *mut _ as *mut c_void;
|
|
||||||
let optlen = &mut name_len as *mut socklen_t;
|
|
||||||
if libc::getsockopt(tun.0, SYSPROTO_CONTROL, UTUN_OPT_IFNAME, optval, optlen) < 0 {
|
|
||||||
return Err(io::Error::last_os_error());
|
|
||||||
}
|
|
||||||
|
|
||||||
let ctl = Fd::new(libc::socket(AF_INET, SOCK_DGRAM, 0))?;
|
|
||||||
|
|
||||||
Device {
|
|
||||||
name: CStr::from_ptr(name.as_ptr() as *const c_char)
|
|
||||||
.to_string_lossy()
|
|
||||||
.into(),
|
|
||||||
tun,
|
|
||||||
ctl,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
device.enabled(true)?;
|
|
||||||
Ok(device)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Device {
|
|
||||||
fn enabled(&self, value: bool) -> io::Result<()> {
|
|
||||||
unsafe {
|
|
||||||
let mut req = self.request();
|
|
||||||
|
|
||||||
if siocgifflags(self.ctl.as_raw_fd(), &mut req) < 0 {
|
|
||||||
return Err(io::Error::last_os_error());
|
|
||||||
}
|
|
||||||
|
|
||||||
if value {
|
|
||||||
req.ifru.flags |= (IFF_UP | IFF_RUNNING) as c_short;
|
|
||||||
} else {
|
|
||||||
req.ifru.flags &= !(IFF_UP as c_short);
|
|
||||||
}
|
|
||||||
|
|
||||||
if siocsifflags(self.ctl.as_raw_fd(), &req) < 0 {
|
|
||||||
return Err(io::Error::last_os_error());
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unsafe fn request(&self) -> ifreq {
|
|
||||||
let mut req: ifreq = mem::zeroed();
|
|
||||||
ptr::copy_nonoverlapping(
|
|
||||||
self.name.as_ptr() as *const c_char,
|
|
||||||
req.ifrn.name.as_mut_ptr(),
|
|
||||||
self.name.len(),
|
|
||||||
);
|
|
||||||
req
|
|
||||||
}
|
|
||||||
fn address(&self) -> io::Result<Ipv4Addr> {
|
|
||||||
unsafe {
|
|
||||||
let mut req = self.request();
|
|
||||||
|
|
||||||
if siocgifaddr(self.ctl.as_raw_fd(), &mut req) < 0 {
|
|
||||||
return Err(io::Error::last_os_error());
|
|
||||||
}
|
|
||||||
|
|
||||||
SockAddr::new(&req.ifru.addr).map(Into::into)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_address(&self, value: Ipv4Addr) -> io::Result<()> {
|
|
||||||
unsafe {
|
|
||||||
let mut req = self.request();
|
|
||||||
req.ifru.addr = SockAddr::from(value).into();
|
|
||||||
|
|
||||||
if siocsifaddr(self.ctl.as_raw_fd(), &req) < 0 {
|
|
||||||
return Err(io::Error::last_os_error());
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn destination(&self) -> io::Result<Ipv4Addr> {
|
|
||||||
unsafe {
|
|
||||||
let mut req = self.request();
|
|
||||||
|
|
||||||
if siocgifdstaddr(self.ctl.as_raw_fd(), &mut req) < 0 {
|
|
||||||
return Err(io::Error::last_os_error());
|
|
||||||
}
|
|
||||||
|
|
||||||
SockAddr::new(&req.ifru.dstaddr).map(Into::into)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_destination(&self, value: Ipv4Addr) -> io::Result<()> {
|
|
||||||
unsafe {
|
|
||||||
let mut req = self.request();
|
|
||||||
req.ifru.dstaddr = SockAddr::from(value).into();
|
|
||||||
|
|
||||||
if siocsifdstaddr(self.ctl.as_raw_fd(), &req) < 0 {
|
|
||||||
return Err(io::Error::last_os_error());
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn broadcast(&self) -> io::Result<Ipv4Addr> {
|
|
||||||
unsafe {
|
|
||||||
let mut req = self.request();
|
|
||||||
|
|
||||||
if siocgifbrdaddr(self.ctl.as_raw_fd(), &mut req) < 0 {
|
|
||||||
return Err(io::Error::last_os_error());
|
|
||||||
}
|
|
||||||
|
|
||||||
SockAddr::new(&req.ifru.broadaddr).map(Into::into)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_broadcast(&self, value: Ipv4Addr) -> io::Result<()> {
|
|
||||||
unsafe {
|
|
||||||
let mut req = self.request();
|
|
||||||
req.ifru.broadaddr = SockAddr::from(value).into();
|
|
||||||
|
|
||||||
if siocsifbrdaddr(self.ctl.as_raw_fd(), &req) < 0 {
|
|
||||||
return Err(io::Error::last_os_error());
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn netmask(&self) -> io::Result<Ipv4Addr> {
|
|
||||||
unsafe {
|
|
||||||
let mut req = self.request();
|
|
||||||
|
|
||||||
if siocgifnetmask(self.ctl.as_raw_fd(), &mut req) < 0 {
|
|
||||||
return Err(io::Error::last_os_error());
|
|
||||||
}
|
|
||||||
|
|
||||||
SockAddr::unchecked(&req.ifru.addr).map(Into::into)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_netmask(&self, value: Ipv4Addr) -> io::Result<()> {
|
|
||||||
unsafe {
|
|
||||||
let mut req = self.request();
|
|
||||||
req.ifru.addr = SockAddr::from(value).into();
|
|
||||||
|
|
||||||
if siocsifnetmask(self.ctl.as_raw_fd(), &req) < 0 {
|
|
||||||
return Err(io::Error::last_os_error());
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl Device {
|
|
||||||
pub fn as_tun_fd(&self) -> &Fd {
|
|
||||||
&self.tun
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl IFace for Device {
|
|
||||||
fn version(&self) -> io::Result<String> {
|
|
||||||
Ok(String::new())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn name(&self) -> io::Result<String> {
|
|
||||||
Ok(self.name.clone())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn shutdown(&self) -> io::Result<()> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_ip(&self, address: Ipv4Addr, mask: Ipv4Addr) -> io::Result<()> {
|
|
||||||
self.set_address(address)?;
|
|
||||||
self.set_netmask(mask)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn mtu(&self) -> io::Result<u32> {
|
|
||||||
unsafe {
|
|
||||||
let mut req = self.request();
|
|
||||||
|
|
||||||
if siocgifmtu(self.ctl.as_raw_fd(), &mut req) < 0 {
|
|
||||||
return Err(io::Error::last_os_error());
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(req.ifru.mtu as _)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_mtu(&self, value: u32) -> io::Result<()> {
|
|
||||||
unsafe {
|
|
||||||
let mut req = self.request();
|
|
||||||
req.ifru.mtu = value as _;
|
|
||||||
|
|
||||||
if siocsifmtu(self.ctl.as_raw_fd(), &req) < 0 {
|
|
||||||
return Err(io::Error::last_os_error());
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn add_route(&self, dest: Ipv4Addr, netmask: Ipv4Addr, _metric: u16) -> io::Result<()> {
|
|
||||||
route::add_route(&self.name, dest, netmask)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn delete_route(&self, dest: Ipv4Addr, netmask: Ipv4Addr) -> io::Result<()> {
|
|
||||||
route::del_route(&self.name, dest, netmask)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
|
|
||||||
self.tun.read(buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
|
||||||
let mut packet = Vec::<u8>::with_capacity(4 + buf.len());
|
|
||||||
packet.push(0);
|
|
||||||
packet.push(0);
|
|
||||||
packet.extend_from_slice(&(libc::PF_INET as u16).to_be_bytes());
|
|
||||||
packet.extend_from_slice(buf);
|
|
||||||
self.tun.write(&packet)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
mod device;
|
|
||||||
pub use device::Device;
|
|
||||||
mod sys;
|
|
||||||
|
|
||||||
mod route;
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
use crate::unix::exe_cmd;
|
|
||||||
use std::io;
|
|
||||||
use std::net::Ipv4Addr;
|
|
||||||
|
|
||||||
pub fn add_route(name: &str, address: Ipv4Addr, netmask: Ipv4Addr) -> io::Result<()> {
|
|
||||||
let cmd = format!(
|
|
||||||
"route -n add {} -netmask {} -interface {}",
|
|
||||||
address, netmask, name
|
|
||||||
);
|
|
||||||
exe_cmd(&cmd)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
pub fn del_route(name: &str, address: Ipv4Addr, netmask: Ipv4Addr) -> io::Result<()> {
|
|
||||||
let cmd = format!(
|
|
||||||
"route -n delete {} -netmask {} -interface {}",
|
|
||||||
address, netmask, name
|
|
||||||
);
|
|
||||||
exe_cmd(&cmd)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
@@ -1,119 +0,0 @@
|
|||||||
//! Bindings to internal macOS stuff.
|
|
||||||
|
|
||||||
use ioctl::*;
|
|
||||||
use libc::{c_char, c_int, c_short, c_uint, c_ushort, c_void, sockaddr, IFNAMSIZ};
|
|
||||||
|
|
||||||
pub const UTUN_CONTROL_NAME: &str = "com.apple.net.utun_control";
|
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
#[repr(C)]
|
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
pub struct ctl_info {
|
|
||||||
pub ctl_id: c_uint,
|
|
||||||
pub ctl_name: [c_char; 96],
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
#[repr(C)]
|
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
pub struct sockaddr_ctl {
|
|
||||||
pub sc_len: c_char,
|
|
||||||
pub sc_family: c_char,
|
|
||||||
pub ss_sysaddr: c_ushort,
|
|
||||||
pub sc_id: c_uint,
|
|
||||||
pub sc_unit: c_uint,
|
|
||||||
pub sc_reserved: [c_uint; 5],
|
|
||||||
}
|
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
pub union ifrn {
|
|
||||||
pub name: [c_char; IFNAMSIZ],
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
#[repr(C)]
|
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
pub struct ifdevmtu {
|
|
||||||
pub current: c_int,
|
|
||||||
pub min: c_int,
|
|
||||||
pub max: c_int,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
pub union ifku {
|
|
||||||
pub ptr: *mut c_void,
|
|
||||||
pub value: c_int,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
#[repr(C)]
|
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
pub struct ifkpi {
|
|
||||||
pub module_id: c_uint,
|
|
||||||
pub type_: c_uint,
|
|
||||||
pub ifku: ifku,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
pub union ifru {
|
|
||||||
pub addr: sockaddr,
|
|
||||||
pub dstaddr: sockaddr,
|
|
||||||
pub broadaddr: sockaddr,
|
|
||||||
|
|
||||||
pub flags: c_short,
|
|
||||||
pub metric: c_int,
|
|
||||||
pub mtu: c_int,
|
|
||||||
pub phys: c_int,
|
|
||||||
pub media: c_int,
|
|
||||||
pub intval: c_int,
|
|
||||||
pub data: *mut c_void,
|
|
||||||
pub devmtu: ifdevmtu,
|
|
||||||
pub wake_flags: c_uint,
|
|
||||||
pub route_refcnt: c_uint,
|
|
||||||
pub cap: [c_int; 2],
|
|
||||||
pub functional_type: c_uint,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
#[repr(C)]
|
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
pub struct ifreq {
|
|
||||||
pub ifrn: ifrn,
|
|
||||||
pub ifru: ifru,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
#[repr(C)]
|
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
pub struct ifaliasreq {
|
|
||||||
pub ifran: [c_char; IFNAMSIZ],
|
|
||||||
pub addr: sockaddr,
|
|
||||||
pub broadaddr: sockaddr,
|
|
||||||
pub mask: sockaddr,
|
|
||||||
}
|
|
||||||
|
|
||||||
ioctl!(readwrite ctliocginfo with 'N', 3; ctl_info);
|
|
||||||
|
|
||||||
ioctl!(write siocsifflags with 'i', 16; ifreq);
|
|
||||||
ioctl!(readwrite siocgifflags with 'i', 17; ifreq);
|
|
||||||
|
|
||||||
ioctl!(write siocsifaddr with 'i', 12; ifreq);
|
|
||||||
ioctl!(readwrite siocgifaddr with 'i', 33; ifreq);
|
|
||||||
|
|
||||||
ioctl!(write siocsifdstaddr with 'i', 14; ifreq);
|
|
||||||
ioctl!(readwrite siocgifdstaddr with 'i', 34; ifreq);
|
|
||||||
|
|
||||||
ioctl!(write siocsifbrdaddr with 'i', 19; ifreq);
|
|
||||||
ioctl!(readwrite siocgifbrdaddr with 'i', 35; ifreq);
|
|
||||||
|
|
||||||
ioctl!(write siocsifnetmask with 'i', 22; ifreq);
|
|
||||||
ioctl!(readwrite siocgifnetmask with 'i', 37; ifreq);
|
|
||||||
|
|
||||||
ioctl!(write siocsifmtu with 'i', 52; ifreq);
|
|
||||||
ioctl!(readwrite siocgifmtu with 'i', 51; ifreq);
|
|
||||||
|
|
||||||
ioctl!(write siocaifaddr with 'i', 26; ifaliasreq);
|
|
||||||
ioctl!(write siocdifaddr with 'i', 25; ifreq);
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
pub mod packet;
|
|
||||||
@@ -1,123 +0,0 @@
|
|||||||
#![allow(dead_code)]
|
|
||||||
use std::{fmt, io};
|
|
||||||
|
|
||||||
/// 地址解析协议,由IP地址找到MAC地址
|
|
||||||
/// https://www.ietf.org/rfc/rfc6747.txt
|
|
||||||
/*
|
|
||||||
0 2 4 5 6 8 10 (字节)
|
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
||||||
| 硬件类型|协议类型|硬件地址长度|协议地址长度|操作类型|
|
|
||||||
| 源MAC地址 | 源ip地址 |
|
|
||||||
| 目的MAC地址 | 目的ip地址 |
|
|
||||||
*/
|
|
||||||
|
|
||||||
pub struct ArpPacket<B> {
|
|
||||||
buffer: B,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<B: AsRef<[u8]>> ArpPacket<B> {
|
|
||||||
pub fn unchecked(buffer: B) -> Self {
|
|
||||||
Self { buffer }
|
|
||||||
}
|
|
||||||
pub fn new(buffer: B) -> io::Result<Self> {
|
|
||||||
if buffer.as_ref().len() != 28 {
|
|
||||||
Err(io::Error::from(io::ErrorKind::InvalidData))?;
|
|
||||||
}
|
|
||||||
let packet = Self::unchecked(buffer);
|
|
||||||
Ok(packet)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<B: AsRef<[u8]>> ArpPacket<B> {
|
|
||||||
/// 硬件类型 以太网类型为1
|
|
||||||
pub fn hardware_type(&self) -> u16 {
|
|
||||||
u16::from_be_bytes(self.buffer.as_ref()[0..2].try_into().unwrap())
|
|
||||||
}
|
|
||||||
/// 上层协议类型,ipv4是0x0800
|
|
||||||
pub fn protocol_type(&self) -> u16 {
|
|
||||||
u16::from_be_bytes(self.buffer.as_ref()[2..4].try_into().unwrap())
|
|
||||||
}
|
|
||||||
/// 如果是MAC地址 则长度为6
|
|
||||||
pub fn hardware_size(&self) -> u8 {
|
|
||||||
self.buffer.as_ref()[4]
|
|
||||||
}
|
|
||||||
/// 如果是IPv4 则长度为4
|
|
||||||
pub fn protocol_size(&self) -> u8 {
|
|
||||||
self.buffer.as_ref()[5]
|
|
||||||
}
|
|
||||||
/// 操作类型,请求和响应 1:ARP请求,2:ARP响应,3:RARP请求,4:RARP响应
|
|
||||||
pub fn op_code(&self) -> u16 {
|
|
||||||
u16::from_be_bytes(self.buffer.as_ref()[6..8].try_into().unwrap())
|
|
||||||
}
|
|
||||||
/// 发送端硬件地址,仅支持以太网
|
|
||||||
pub fn sender_hardware_addr(&self) -> &[u8] {
|
|
||||||
&self.buffer.as_ref()[8..14]
|
|
||||||
}
|
|
||||||
/// 发送端协议地址,仅支持IPv4
|
|
||||||
pub fn sender_protocol_addr(&self) -> &[u8] {
|
|
||||||
&self.buffer.as_ref()[14..18]
|
|
||||||
}
|
|
||||||
/// 接收端硬件地址,仅支持以太网
|
|
||||||
pub fn target_hardware_addr(&self) -> &[u8] {
|
|
||||||
&self.buffer.as_ref()[18..24]
|
|
||||||
}
|
|
||||||
/// 接收端协议地址,仅支持IPv4
|
|
||||||
pub fn target_protocol_addr(&self) -> &[u8] {
|
|
||||||
&self.buffer.as_ref()[24..28]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<B: AsRef<[u8]> + AsMut<[u8]>> ArpPacket<B> {
|
|
||||||
/// 硬件类型 以太网类型为1
|
|
||||||
pub fn set_hardware_type(&mut self, value: u16) {
|
|
||||||
self.buffer.as_mut()[0..2].copy_from_slice(&value.to_be_bytes())
|
|
||||||
}
|
|
||||||
/// 上层协议类型,ipv4是0x0800
|
|
||||||
pub fn set_protocol_type(&mut self, value: u16) {
|
|
||||||
self.buffer.as_mut()[2..4].copy_from_slice(&value.to_be_bytes())
|
|
||||||
}
|
|
||||||
/// 如果是MAC地址 则长度为6
|
|
||||||
pub fn set_hardware_size(&mut self, value: u8) {
|
|
||||||
self.buffer.as_mut()[4] = value
|
|
||||||
}
|
|
||||||
/// 如果是IPv4 则长度为4
|
|
||||||
pub fn set_protocol_size(&mut self, value: u8) {
|
|
||||||
self.buffer.as_mut()[5] = value
|
|
||||||
}
|
|
||||||
/// 操作类型,请求和响应 1:ARP请求,2:ARP响应,3:RARP请求,4:RARP响应
|
|
||||||
pub fn set_op_code(&mut self, value: u16) {
|
|
||||||
self.buffer.as_mut()[6..8].copy_from_slice(&value.to_be_bytes())
|
|
||||||
}
|
|
||||||
/// 发送端硬件地址,仅支持以太网
|
|
||||||
pub fn set_sender_hardware_addr(&mut self, buf: &[u8]) {
|
|
||||||
self.buffer.as_mut()[8..14].copy_from_slice(buf)
|
|
||||||
}
|
|
||||||
/// 发送端协议地址,仅支持IPv4
|
|
||||||
pub fn set_sender_protocol_addr(&mut self, buf: &[u8]) {
|
|
||||||
self.buffer.as_mut()[14..18].copy_from_slice(buf)
|
|
||||||
}
|
|
||||||
/// 接收端硬件地址,仅支持以太网
|
|
||||||
pub fn set_target_hardware_addr(&mut self, buf: &[u8]) {
|
|
||||||
self.buffer.as_mut()[18..24].copy_from_slice(buf)
|
|
||||||
}
|
|
||||||
/// 接收端协议地址,仅支持IPv4
|
|
||||||
pub fn set_target_protocol_addr(&mut self, buf: &[u8]) {
|
|
||||||
self.buffer.as_mut()[24..28].copy_from_slice(buf)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<B: AsRef<[u8]>> fmt::Debug for ArpPacket<B> {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
f.debug_struct("ArpPacket")
|
|
||||||
.field("hardware_type", &self.hardware_type())
|
|
||||||
.field("protocol_type", &self.protocol_type())
|
|
||||||
.field("hardware_size", &self.hardware_size())
|
|
||||||
.field("protocol_size", &self.protocol_size())
|
|
||||||
.field("op_code", &self.op_code())
|
|
||||||
.field("sender_hardware_addr", &self.sender_hardware_addr())
|
|
||||||
.field("sender_protocol_addr", &self.sender_protocol_addr())
|
|
||||||
.field("target_hardware_addr", &self.target_hardware_addr())
|
|
||||||
.field("target_protocol_addr", &self.target_protocol_addr())
|
|
||||||
.finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
pub mod packet;
|
|
||||||
pub mod protocol;
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
use crate::packet::ethernet::protocol::Protocol;
|
|
||||||
use std::{fmt, io};
|
|
||||||
|
|
||||||
/// 以太网帧协议
|
|
||||||
/// https://www.ietf.org/rfc/rfc894.txt
|
|
||||||
/*
|
|
||||||
0 6 12 14 (字节)
|
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
||||||
| 目的地址 | 源地址 | 类型 |
|
|
||||||
*/
|
|
||||||
pub struct EthernetPacket<B> {
|
|
||||||
pub buffer: B,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<B: AsRef<[u8]>> EthernetPacket<B> {
|
|
||||||
pub fn unchecked(buffer: B) -> EthernetPacket<B> {
|
|
||||||
EthernetPacket { buffer }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new(buffer: B) -> io::Result<EthernetPacket<B>> {
|
|
||||||
let packet = EthernetPacket::unchecked(buffer);
|
|
||||||
//头部固定14位
|
|
||||||
if packet.buffer.as_ref().len() < 14 {
|
|
||||||
Err(io::Error::new(
|
|
||||||
io::ErrorKind::InvalidData,
|
|
||||||
format!("len={}", packet.buffer.as_ref().len()),
|
|
||||||
))?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(packet)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<B: AsRef<[u8]>> EthernetPacket<B> {
|
|
||||||
/// 目的MAC地址
|
|
||||||
pub fn destination(&self) -> &[u8] {
|
|
||||||
&self.buffer.as_ref()[0..6]
|
|
||||||
}
|
|
||||||
/// 源MAC地址
|
|
||||||
pub fn source(&self) -> &[u8] {
|
|
||||||
&self.buffer.as_ref()[6..12]
|
|
||||||
}
|
|
||||||
/// 3层协议
|
|
||||||
pub fn protocol(&self) -> Protocol {
|
|
||||||
u16::from_be_bytes(self.buffer.as_ref()[12..14].try_into().unwrap()).into()
|
|
||||||
}
|
|
||||||
/// 载荷
|
|
||||||
pub fn payload(&self) -> &[u8] {
|
|
||||||
&self.buffer.as_ref()[14..]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<B: AsRef<[u8]> + AsMut<[u8]>> EthernetPacket<B> {
|
|
||||||
pub fn set_destination(&mut self, value: &[u8]) {
|
|
||||||
self.buffer.as_mut()[0..6].copy_from_slice(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_source(&mut self, value: &[u8]) {
|
|
||||||
self.buffer.as_mut()[6..12].copy_from_slice(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_protocol(&mut self, value: Protocol) {
|
|
||||||
let p: u16 = value.into();
|
|
||||||
self.buffer.as_mut()[12..14].copy_from_slice(&p.to_be_bytes())
|
|
||||||
}
|
|
||||||
pub fn payload_mut(&mut self) -> &mut [u8] {
|
|
||||||
&mut self.buffer.as_mut()[14..]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<B: AsRef<[u8]>> fmt::Debug for EthernetPacket<B> {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
f.debug_struct("EthernetPacket")
|
|
||||||
.field("destination", &self.destination())
|
|
||||||
.field("source", &self.source())
|
|
||||||
.field("protocol", &self.protocol())
|
|
||||||
.field("payload", &self.payload())
|
|
||||||
.finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,141 +0,0 @@
|
|||||||
/// 以太网帧协议
|
|
||||||
#[derive(Eq, PartialEq, Copy, Clone, Debug)]
|
|
||||||
pub enum Protocol {
|
|
||||||
///
|
|
||||||
Ipv4,
|
|
||||||
|
|
||||||
///
|
|
||||||
Arp,
|
|
||||||
|
|
||||||
///
|
|
||||||
WakeOnLan,
|
|
||||||
|
|
||||||
///
|
|
||||||
Trill,
|
|
||||||
|
|
||||||
///
|
|
||||||
DecNet,
|
|
||||||
|
|
||||||
///
|
|
||||||
Rarp,
|
|
||||||
|
|
||||||
///
|
|
||||||
AppleTalk,
|
|
||||||
|
|
||||||
///
|
|
||||||
Aarp,
|
|
||||||
|
|
||||||
///
|
|
||||||
Ipx,
|
|
||||||
|
|
||||||
///
|
|
||||||
Qnx,
|
|
||||||
|
|
||||||
///
|
|
||||||
Ipv6,
|
|
||||||
|
|
||||||
///
|
|
||||||
FlowControl,
|
|
||||||
|
|
||||||
///
|
|
||||||
CobraNet,
|
|
||||||
|
|
||||||
///
|
|
||||||
Mpls,
|
|
||||||
|
|
||||||
///
|
|
||||||
MplsMulticast,
|
|
||||||
|
|
||||||
///
|
|
||||||
PppoeDiscovery,
|
|
||||||
|
|
||||||
///
|
|
||||||
PppoeSession,
|
|
||||||
|
|
||||||
///
|
|
||||||
Vlan,
|
|
||||||
|
|
||||||
///
|
|
||||||
PBridge,
|
|
||||||
|
|
||||||
///
|
|
||||||
Lldp,
|
|
||||||
|
|
||||||
///
|
|
||||||
Ptp,
|
|
||||||
|
|
||||||
///
|
|
||||||
Cfm,
|
|
||||||
|
|
||||||
///
|
|
||||||
QinQ,
|
|
||||||
|
|
||||||
///
|
|
||||||
Unknown(u16),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<u16> for Protocol {
|
|
||||||
fn from(value: u16) -> Protocol {
|
|
||||||
use self::Protocol::*;
|
|
||||||
|
|
||||||
match value {
|
|
||||||
0x0800 => Ipv4,
|
|
||||||
0x0806 => Arp,
|
|
||||||
0x0842 => WakeOnLan,
|
|
||||||
0x22f3 => Trill,
|
|
||||||
0x6003 => DecNet,
|
|
||||||
0x8035 => Rarp,
|
|
||||||
0x809b => AppleTalk,
|
|
||||||
0x80f3 => Aarp,
|
|
||||||
0x8137 => Ipx,
|
|
||||||
0x8204 => Qnx,
|
|
||||||
0x86dd => Ipv6,
|
|
||||||
0x8808 => FlowControl,
|
|
||||||
0x8819 => CobraNet,
|
|
||||||
0x8847 => Mpls,
|
|
||||||
0x8848 => MplsMulticast,
|
|
||||||
0x8863 => PppoeDiscovery,
|
|
||||||
0x8864 => PppoeSession,
|
|
||||||
0x8100 => Vlan,
|
|
||||||
0x88a8 => PBridge,
|
|
||||||
0x88cc => Lldp,
|
|
||||||
0x88f7 => Ptp,
|
|
||||||
0x8902 => Cfm,
|
|
||||||
0x9100 => QinQ,
|
|
||||||
n => Unknown(n),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Into<u16> for Protocol {
|
|
||||||
fn into(self) -> u16 {
|
|
||||||
use self::Protocol::*;
|
|
||||||
|
|
||||||
match self {
|
|
||||||
Ipv4 => 0x0800,
|
|
||||||
Arp => 0x0806,
|
|
||||||
WakeOnLan => 0x0842,
|
|
||||||
Trill => 0x22f3,
|
|
||||||
DecNet => 0x6003,
|
|
||||||
Rarp => 0x8035,
|
|
||||||
AppleTalk => 0x809b,
|
|
||||||
Aarp => 0x80f3,
|
|
||||||
Ipx => 0x8137,
|
|
||||||
Qnx => 0x8204,
|
|
||||||
Ipv6 => 0x86dd,
|
|
||||||
FlowControl => 0x8808,
|
|
||||||
CobraNet => 0x8819,
|
|
||||||
Mpls => 0x8847,
|
|
||||||
MplsMulticast => 0x8848,
|
|
||||||
PppoeDiscovery => 0x8863,
|
|
||||||
PppoeSession => 0x8864,
|
|
||||||
Vlan => 0x8100,
|
|
||||||
PBridge => 0x88a8,
|
|
||||||
Lldp => 0x88cc,
|
|
||||||
Ptp => 0x88f7,
|
|
||||||
Cfm => 0x8902,
|
|
||||||
QinQ => 0x9100,
|
|
||||||
Unknown(n) => n,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
use crate::packet::ethernet::protocol::Protocol;
|
|
||||||
use std::io;
|
|
||||||
|
|
||||||
pub mod arp;
|
|
||||||
pub mod ethernet;
|
|
||||||
|
|
||||||
const MAC: [u8; 6] = [0xf, 0xf, 0xf, 0xf, 0xe, 0x9];
|
|
||||||
pub fn read_tap<W, R>(buf: &mut [u8], read_fn: R, write_fn: W) -> io::Result<usize>
|
|
||||||
where
|
|
||||||
W: Fn(&[u8]) -> io::Result<usize>,
|
|
||||||
R: Fn(&mut [u8]) -> io::Result<usize>,
|
|
||||||
{
|
|
||||||
let mut eth_buf = [0; 65536];
|
|
||||||
loop {
|
|
||||||
let len = read_fn(&mut eth_buf)?;
|
|
||||||
if len == 0 {
|
|
||||||
return Ok(len);
|
|
||||||
}
|
|
||||||
//处理arp包
|
|
||||||
let mut ether = ethernet::packet::EthernetPacket::new(&mut eth_buf[..len])?;
|
|
||||||
match ether.protocol() {
|
|
||||||
Protocol::Ipv4 => {
|
|
||||||
let len = ether.payload().len();
|
|
||||||
if len > buf.len() {
|
|
||||||
return Err(io::Error::new(io::ErrorKind::Other, "short"));
|
|
||||||
}
|
|
||||||
buf[..len].copy_from_slice(ether.payload());
|
|
||||||
return Ok(len);
|
|
||||||
}
|
|
||||||
Protocol::Arp => {
|
|
||||||
let mut arp_packet = arp::packet::ArpPacket::unchecked(ether.payload_mut());
|
|
||||||
let sender_h: [u8; 6] = arp_packet.sender_hardware_addr().try_into().unwrap();
|
|
||||||
let sender_p: [u8; 4] = arp_packet.sender_protocol_addr().try_into().unwrap();
|
|
||||||
let target_p: [u8; 4] = arp_packet.target_protocol_addr().try_into().unwrap();
|
|
||||||
if target_p == [0, 0, 0, 0] || sender_p == [0, 0, 0, 0] || target_p == sender_p {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if arp_packet.op_code() == 1 {
|
|
||||||
//回复一个默认的MAC
|
|
||||||
arp_packet.set_op_code(2);
|
|
||||||
arp_packet.set_target_hardware_addr(&sender_h);
|
|
||||||
arp_packet.set_target_protocol_addr(&sender_p);
|
|
||||||
arp_packet.set_sender_protocol_addr(&target_p);
|
|
||||||
arp_packet.set_sender_hardware_addr(&MAC);
|
|
||||||
ether.set_destination(&sender_h);
|
|
||||||
ether.set_source(&MAC);
|
|
||||||
write_fn(ether.buffer)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
//忽略这些数据
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn write_tap<W>(buf: &[u8], write_fn: W, mac: &[u8; 6]) -> io::Result<usize>
|
|
||||||
where
|
|
||||||
W: Fn(&[u8]) -> io::Result<usize>,
|
|
||||||
{
|
|
||||||
// 封装二层数据
|
|
||||||
let mut ether = ethernet::packet::EthernetPacket::unchecked(vec![0; 14 + buf.len()]);
|
|
||||||
ether.set_source(&MAC);
|
|
||||||
ether.set_destination(mac);
|
|
||||||
ether.set_protocol(Protocol::Ipv4);
|
|
||||||
ether.payload_mut().copy_from_slice(buf);
|
|
||||||
write_fn(ðer.buffer)
|
|
||||||
}
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
use libc::{fcntl, F_GETFL, F_SETFL, O_NONBLOCK};
|
|
||||||
use std::io;
|
|
||||||
use std::os::fd::{AsRawFd, IntoRawFd, RawFd};
|
|
||||||
|
|
||||||
pub struct Fd(pub RawFd);
|
|
||||||
|
|
||||||
impl Fd {
|
|
||||||
pub fn new(value: RawFd) -> io::Result<Self> {
|
|
||||||
if value < 0 {
|
|
||||||
return Err(io::Error::from(io::ErrorKind::InvalidInput));
|
|
||||||
}
|
|
||||||
Ok(Fd(value))
|
|
||||||
}
|
|
||||||
pub fn set_nonblock(&self) -> io::Result<()> {
|
|
||||||
match unsafe { fcntl(self.0, F_SETFL, fcntl(self.0, F_GETFL) | O_NONBLOCK) } {
|
|
||||||
0 => Ok(()),
|
|
||||||
_ => Err(io::Error::last_os_error()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Fd {
|
|
||||||
pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
|
|
||||||
unsafe {
|
|
||||||
let amount = libc::read(self.0, buf.as_mut_ptr() as *mut _, buf.len());
|
|
||||||
|
|
||||||
if amount < 0 {
|
|
||||||
return Err(io::Error::last_os_error());
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(amount as usize)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
|
||||||
unsafe {
|
|
||||||
let amount = libc::write(self.0, buf.as_ptr() as *const _, buf.len());
|
|
||||||
|
|
||||||
if amount < 0 {
|
|
||||||
return Err(io::Error::last_os_error());
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(amount as usize)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AsRawFd for Fd {
|
|
||||||
fn as_raw_fd(&self) -> RawFd {
|
|
||||||
self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl IntoRawFd for Fd {
|
|
||||||
fn into_raw_fd(mut self) -> RawFd {
|
|
||||||
let fd = self.0;
|
|
||||||
self.0 = -1;
|
|
||||||
fd
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(target_os = "android"))]
|
|
||||||
impl Drop for Fd {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
unsafe {
|
|
||||||
libc::close(self.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
mod fd;
|
|
||||||
|
|
||||||
pub use fd::Fd;
|
|
||||||
#[cfg(any(target_os = "macos", target_os = "linux"))]
|
|
||||||
use std::process::Output;
|
|
||||||
#[cfg(any(target_os = "macos", target_os = "linux"))]
|
|
||||||
mod sockaddr;
|
|
||||||
#[cfg(any(target_os = "macos", target_os = "linux"))]
|
|
||||||
pub use sockaddr::SockAddr;
|
|
||||||
|
|
||||||
#[cfg(any(target_os = "macos", target_os = "linux"))]
|
|
||||||
pub fn exe_cmd(cmd: &str) -> std::io::Result<Output> {
|
|
||||||
use std::io;
|
|
||||||
use std::process::Command;
|
|
||||||
println!("exe cmd: {}", cmd);
|
|
||||||
let out = Command::new("sh")
|
|
||||||
.arg("-c")
|
|
||||||
.arg(cmd)
|
|
||||||
.output()
|
|
||||||
.expect("sh exec error!");
|
|
||||||
if !out.status.success() {
|
|
||||||
return Err(io::Error::new(
|
|
||||||
io::ErrorKind::Other,
|
|
||||||
format!("cmd={},out={:?}", cmd, out),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
Ok(out)
|
|
||||||
}
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
use libc::{in_addr, sockaddr, sockaddr_in};
|
|
||||||
use std::{io, mem, net::Ipv4Addr, ptr};
|
|
||||||
|
|
||||||
use io::Result;
|
|
||||||
|
|
||||||
/// A wrapper for `sockaddr_in`.
|
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
pub struct SockAddr(sockaddr_in);
|
|
||||||
|
|
||||||
impl SockAddr {
|
|
||||||
/// Create a new `SockAddr` from a generic `sockaddr`.
|
|
||||||
pub fn new(value: &sockaddr) -> Result<Self> {
|
|
||||||
if value.sa_family != libc::AF_INET as libc::sa_family_t {
|
|
||||||
return Err(io::Error::new(io::ErrorKind::Other, "invalid address"));
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe { Self::unchecked(value) }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// # Safety
|
|
||||||
/// Create a new `SockAddr` and not check the source.
|
|
||||||
pub unsafe fn unchecked(value: &sockaddr) -> Result<Self> {
|
|
||||||
Ok(SockAddr(ptr::read(value as *const _ as *const _)))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// # Safety
|
|
||||||
/// Get a generic pointer to the `SockAddr`.
|
|
||||||
pub unsafe fn as_ptr(&self) -> *const sockaddr {
|
|
||||||
&self.0 as *const _ as *const sockaddr
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Ipv4Addr> for SockAddr {
|
|
||||||
fn from(ip: Ipv4Addr) -> SockAddr {
|
|
||||||
let octets = ip.octets();
|
|
||||||
let mut addr = unsafe { mem::zeroed::<sockaddr_in>() };
|
|
||||||
|
|
||||||
addr.sin_family = libc::AF_INET as libc::sa_family_t;
|
|
||||||
addr.sin_port = 0;
|
|
||||||
addr.sin_addr = in_addr {
|
|
||||||
s_addr: u32::from_ne_bytes(octets),
|
|
||||||
};
|
|
||||||
|
|
||||||
SockAddr(addr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<SockAddr> for Ipv4Addr {
|
|
||||||
fn from(addr: SockAddr) -> Ipv4Addr {
|
|
||||||
let ip = addr.0.sin_addr.s_addr;
|
|
||||||
let [a, b, c, d] = ip.to_ne_bytes();
|
|
||||||
|
|
||||||
Ipv4Addr::new(a, b, c, d)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<SockAddr> for sockaddr {
|
|
||||||
fn from(addr: SockAddr) -> sockaddr {
|
|
||||||
unsafe { mem::transmute(addr.0) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<SockAddr> for sockaddr_in {
|
|
||||||
fn from(addr: SockAddr) -> sockaddr_in {
|
|
||||||
addr.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,167 +0,0 @@
|
|||||||
use libloading::Library;
|
|
||||||
use std::ffi::{c_char, CStr, CString};
|
|
||||||
use std::fs::File;
|
|
||||||
use std::io::{self, Read, Seek};
|
|
||||||
use std::path::PathBuf;
|
|
||||||
use winapi::shared::minwindef::HINSTANCE;
|
|
||||||
use winapi::um::libloaderapi::{GetModuleFileNameA, GetModuleHandleA};
|
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
#[derive(Debug)]
|
|
||||||
struct DosHeader {
|
|
||||||
e_magic: u16,
|
|
||||||
e_cblp: u16,
|
|
||||||
e_cp: u16,
|
|
||||||
e_crlc: u16,
|
|
||||||
e_cparhdr: u16,
|
|
||||||
e_minalloc: u16,
|
|
||||||
e_maxalloc: u16,
|
|
||||||
e_ss: u16,
|
|
||||||
e_sp: u16,
|
|
||||||
e_csum: u16,
|
|
||||||
e_ip: u16,
|
|
||||||
e_cs: u16,
|
|
||||||
e_lfarlc: u16,
|
|
||||||
e_ovno: u16,
|
|
||||||
e_res: [u16; 4],
|
|
||||||
e_oemid: u16,
|
|
||||||
e_oeminfo: u16,
|
|
||||||
e_res2: [u16; 10],
|
|
||||||
e_lfanew: i32,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
#[derive(Debug)]
|
|
||||||
struct FileHeader {
|
|
||||||
machine: u16,
|
|
||||||
number_of_sections: u16,
|
|
||||||
time_date_stamp: u32,
|
|
||||||
pointer_to_symbol_table: u32,
|
|
||||||
number_of_symbols: u32,
|
|
||||||
size_of_optional_header: u16,
|
|
||||||
characteristics: u16,
|
|
||||||
}
|
|
||||||
|
|
||||||
const IMAGE_FILE_MACHINE_I386: u16 = 0x014C;
|
|
||||||
const IMAGE_FILE_MACHINE_AMD64: u16 = 0x8664;
|
|
||||||
const IMAGE_FILE_MACHINE_ARM: u16 = 0x01C4;
|
|
||||||
const IMAGE_FILE_MACHINE_ARM64: u16 = 0xAA64;
|
|
||||||
|
|
||||||
fn get_dll_path(dll_name: &str) -> Result<PathBuf, String> {
|
|
||||||
unsafe {
|
|
||||||
// 使用libloading加载DLL
|
|
||||||
|
|
||||||
// 转换DLL名称为C字符串
|
|
||||||
let dll_name_c =
|
|
||||||
CString::new(dll_name).map_err(|e| format!("Failed to convert to CString: {}", e))?;
|
|
||||||
|
|
||||||
// 获取DLL的模块句柄
|
|
||||||
let h_instance: HINSTANCE = GetModuleHandleA(dll_name_c.as_ptr() as *const c_char);
|
|
||||||
|
|
||||||
if h_instance.is_null() {
|
|
||||||
return Err("Failed to get module handle".to_string());
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取DLL文件路径
|
|
||||||
let mut buffer: [c_char; 260] = [0; 260];
|
|
||||||
let length = GetModuleFileNameA(h_instance, buffer.as_mut_ptr(), buffer.len() as u32);
|
|
||||||
|
|
||||||
if length == 0 {
|
|
||||||
return Err("Failed to get module file name".to_string());
|
|
||||||
}
|
|
||||||
|
|
||||||
let path = CStr::from_ptr(buffer.as_ptr());
|
|
||||||
let path_str = path
|
|
||||||
.to_str()
|
|
||||||
.map_err(|e| format!("Failed to convert to &str: {}", e))?;
|
|
||||||
Ok(PathBuf::from(path_str))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn check_win_tun_dll() -> io::Result<()> {
|
|
||||||
let _lib = unsafe {
|
|
||||||
Library::new("wintun.dll").map_err(|_| {
|
|
||||||
io::Error::new(
|
|
||||||
io::ErrorKind::NotFound,
|
|
||||||
"wintun.dll not found,Please download https://www.wintun.net",
|
|
||||||
)
|
|
||||||
})
|
|
||||||
};
|
|
||||||
match get_dll_path("wintun.dll") {
|
|
||||||
Ok(path) => match_platform(path),
|
|
||||||
Err(e) => {
|
|
||||||
// 能加载说明存在wintun,这里获取不到路径是代码的问题
|
|
||||||
log::info!("{:?}", e);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn match_platform(path: PathBuf) -> io::Result<()> {
|
|
||||||
let current_arch = if cfg!(target_arch = "x86") {
|
|
||||||
"x86"
|
|
||||||
} else if cfg!(target_arch = "x86_64") {
|
|
||||||
"AMD64"
|
|
||||||
} else if cfg!(target_arch = "arm") {
|
|
||||||
"ARM"
|
|
||||||
} else if cfg!(target_arch = "aarch64") {
|
|
||||||
"ARM64"
|
|
||||||
} else {
|
|
||||||
return Ok(());
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut file = File::open(&path)?;
|
|
||||||
|
|
||||||
// 读取 DOS 头部
|
|
||||||
let mut dos_header = [0u8; std::mem::size_of::<DosHeader>()];
|
|
||||||
file.read_exact(&mut dos_header)?;
|
|
||||||
let dos_header: DosHeader = unsafe { std::ptr::read(dos_header.as_ptr() as *const _) };
|
|
||||||
|
|
||||||
if dos_header.e_magic != 0x5A4D {
|
|
||||||
return Err(io::Error::new(
|
|
||||||
io::ErrorKind::Other,
|
|
||||||
format!("Not a valid PE file {:?}", path),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 跳转到 PE 头部
|
|
||||||
file.seek(io::SeekFrom::Start(dos_header.e_lfanew as u64))?;
|
|
||||||
|
|
||||||
// 读取 PE 头部
|
|
||||||
let mut pe_signature = [0u8; 4];
|
|
||||||
file.read_exact(&mut pe_signature)?;
|
|
||||||
if &pe_signature != b"PE\0\0" {
|
|
||||||
return Err(io::Error::new(
|
|
||||||
io::ErrorKind::Other,
|
|
||||||
format!("Not a valid PE file {:?}", path),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 读取文件头部
|
|
||||||
let mut file_header = [0u8; std::mem::size_of::<FileHeader>()];
|
|
||||||
file.read_exact(&mut file_header)?;
|
|
||||||
let file_header: FileHeader = unsafe { std::ptr::read(file_header.as_ptr() as *const _) };
|
|
||||||
let dll_arch = match file_header.machine {
|
|
||||||
IMAGE_FILE_MACHINE_I386 => "x86",
|
|
||||||
IMAGE_FILE_MACHINE_AMD64 => "AMD64",
|
|
||||||
IMAGE_FILE_MACHINE_ARM => "ARM",
|
|
||||||
IMAGE_FILE_MACHINE_ARM64 => "ARM64",
|
|
||||||
_ => {
|
|
||||||
return Err(io::Error::new(
|
|
||||||
io::ErrorKind::Other,
|
|
||||||
format!("Unknown machine type: {}", file_header.machine),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if dll_arch != current_arch {
|
|
||||||
return Err(io::Error::new(
|
|
||||||
io::ErrorKind::Other,
|
|
||||||
format!(
|
|
||||||
"wintun.dll architecture ({}) does not match the current platform architecture ({}).",
|
|
||||||
dll_arch, current_arch
|
|
||||||
),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
@@ -1,94 +0,0 @@
|
|||||||
use crate::device::IFace;
|
|
||||||
use crate::windows::{tap, tun};
|
|
||||||
use std::io;
|
|
||||||
use std::net::Ipv4Addr;
|
|
||||||
|
|
||||||
pub enum Device {
|
|
||||||
Tap(tap::Device),
|
|
||||||
Tun(tun::Device),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Device {
|
|
||||||
pub fn new(name: String, tap: bool) -> io::Result<Self> {
|
|
||||||
if tap {
|
|
||||||
Ok(Device::Tap(tap::Device::new(name)?))
|
|
||||||
} else {
|
|
||||||
Ok(Device::Tun(tun::Device::new(name)?))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn check_tun_dll() -> io::Result<()> {
|
|
||||||
crate::windows::check::check_win_tun_dll()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl IFace for Device {
|
|
||||||
fn version(&self) -> io::Result<String> {
|
|
||||||
match self {
|
|
||||||
Device::Tap(dev) => dev.version(),
|
|
||||||
Device::Tun(dev) => dev.version(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn name(&self) -> io::Result<String> {
|
|
||||||
match self {
|
|
||||||
Device::Tap(dev) => dev.name(),
|
|
||||||
Device::Tun(dev) => dev.name(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn shutdown(&self) -> io::Result<()> {
|
|
||||||
match self {
|
|
||||||
Device::Tap(dev) => dev.shutdown(),
|
|
||||||
Device::Tun(dev) => dev.shutdown(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_ip(&self, address: Ipv4Addr, mask: Ipv4Addr) -> io::Result<()> {
|
|
||||||
match self {
|
|
||||||
Device::Tap(dev) => dev.set_ip(address, mask),
|
|
||||||
Device::Tun(dev) => dev.set_ip(address, mask),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn mtu(&self) -> io::Result<u32> {
|
|
||||||
match self {
|
|
||||||
Device::Tap(dev) => dev.mtu(),
|
|
||||||
Device::Tun(dev) => dev.mtu(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_mtu(&self, value: u32) -> io::Result<()> {
|
|
||||||
match self {
|
|
||||||
Device::Tap(dev) => dev.set_mtu(value),
|
|
||||||
Device::Tun(dev) => dev.set_mtu(value),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn add_route(&self, dest: Ipv4Addr, netmask: Ipv4Addr, metric: u16) -> io::Result<()> {
|
|
||||||
match self {
|
|
||||||
Device::Tap(dev) => dev.add_route(dest, netmask, metric),
|
|
||||||
Device::Tun(dev) => dev.add_route(dest, netmask, metric),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn delete_route(&self, dest: Ipv4Addr, netmask: Ipv4Addr) -> io::Result<()> {
|
|
||||||
match self {
|
|
||||||
Device::Tap(dev) => dev.delete_route(dest, netmask),
|
|
||||||
Device::Tun(dev) => dev.delete_route(dest, netmask),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
|
|
||||||
match self {
|
|
||||||
Device::Tap(dev) => dev.read(buf),
|
|
||||||
Device::Tun(dev) => dev.read(buf),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
|
||||||
match self {
|
|
||||||
Device::Tap(dev) => dev.write(buf),
|
|
||||||
Device::Tun(dev) => dev.write(buf),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,502 +0,0 @@
|
|||||||
// Many things will be used in the future
|
|
||||||
#![allow(unused)]
|
|
||||||
|
|
||||||
//! Module holding safe wrappers over winapi functions
|
|
||||||
|
|
||||||
use winapi::shared::basetsd::*;
|
|
||||||
use winapi::shared::guiddef::GUID;
|
|
||||||
use winapi::shared::ifdef::*;
|
|
||||||
use winapi::shared::minwindef::*;
|
|
||||||
use winapi::shared::netioapi::*;
|
|
||||||
use winapi::shared::winerror::*;
|
|
||||||
|
|
||||||
use winapi::um::combaseapi::*;
|
|
||||||
use winapi::um::errhandlingapi::*;
|
|
||||||
use winapi::um::fileapi::*;
|
|
||||||
use winapi::um::handleapi::*;
|
|
||||||
use winapi::um::ioapiset::*;
|
|
||||||
use winapi::um::setupapi::*;
|
|
||||||
use winapi::um::synchapi::*;
|
|
||||||
use winapi::um::winioctl::*;
|
|
||||||
use winapi::um::winnt::*;
|
|
||||||
use winapi::um::winreg::*;
|
|
||||||
|
|
||||||
use std::error::Error;
|
|
||||||
use std::{io, mem, ptr};
|
|
||||||
use winapi::um::minwinbase::OVERLAPPED_u;
|
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
#[allow(non_snake_case)]
|
|
||||||
#[repr(C)]
|
|
||||||
#[derive(Clone, Copy)]
|
|
||||||
/// Custom type to handle variable size SP_DRVINFO_DETAIL_DATA_W
|
|
||||||
pub struct SP_DRVINFO_DETAIL_DATA_W2 {
|
|
||||||
pub cbSize: DWORD,
|
|
||||||
pub InfDate: FILETIME,
|
|
||||||
pub CompatIDsOffset: DWORD,
|
|
||||||
pub CompatIDsLength: DWORD,
|
|
||||||
pub Reserved: ULONG_PTR,
|
|
||||||
pub SectionName: [WCHAR; 256],
|
|
||||||
pub InfFileName: [WCHAR; 260],
|
|
||||||
pub DrvDescription: [WCHAR; 256],
|
|
||||||
pub HardwareID: [WCHAR; 512],
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn string_from_guid(guid: &GUID) -> io::Result<Vec<WCHAR>> {
|
|
||||||
// GUID_STRING_CHARACTERS + 1
|
|
||||||
let mut string = vec![0; 39];
|
|
||||||
|
|
||||||
match unsafe { StringFromGUID2(guid, string.as_mut_ptr(), string.len() as _) } {
|
|
||||||
0 => Err(io::Error::new(io::ErrorKind::Other, "Insufficent buffer")),
|
|
||||||
_ => Ok(string),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn alias_to_luid(alias: &[WCHAR]) -> io::Result<NET_LUID> {
|
|
||||||
let mut luid = unsafe { mem::zeroed() };
|
|
||||||
|
|
||||||
match unsafe { ConvertInterfaceAliasToLuid(alias.as_ptr(), &mut luid) } {
|
|
||||||
0 => Ok(luid),
|
|
||||||
err => Err(io::Error::from_raw_os_error(err as _)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn luid_to_index(luid: &NET_LUID) -> io::Result<NET_IFINDEX> {
|
|
||||||
let mut index = 0;
|
|
||||||
|
|
||||||
match unsafe { ConvertInterfaceLuidToIndex(luid, &mut index) } {
|
|
||||||
0 => Ok(index),
|
|
||||||
err => Err(io::Error::from_raw_os_error(err as _)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn luid_to_guid(luid: &NET_LUID) -> io::Result<GUID> {
|
|
||||||
let mut guid = unsafe { mem::zeroed() };
|
|
||||||
|
|
||||||
match unsafe { ConvertInterfaceLuidToGuid(luid, &mut guid) } {
|
|
||||||
0 => Ok(guid),
|
|
||||||
err => Err(io::Error::from_raw_os_error(err as _)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn luid_to_alias(luid: &NET_LUID) -> io::Result<Vec<WCHAR>> {
|
|
||||||
// IF_MAX_STRING_SIZE + 1
|
|
||||||
let mut alias = vec![0; 257];
|
|
||||||
|
|
||||||
match unsafe { ConvertInterfaceLuidToAlias(luid, alias.as_mut_ptr(), alias.len()) } {
|
|
||||||
0 => Ok(alias),
|
|
||||||
err => Err(io::Error::from_raw_os_error(err as _)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn close_handle(handle: HANDLE) -> io::Result<()> {
|
|
||||||
match unsafe { CloseHandle(handle) } {
|
|
||||||
0 => Err(io::Error::last_os_error()),
|
|
||||||
_ => Ok(()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn create_file(
|
|
||||||
file_name: &[WCHAR],
|
|
||||||
desired_access: DWORD,
|
|
||||||
share_mode: DWORD,
|
|
||||||
creation_disposition: DWORD,
|
|
||||||
flags_and_attributes: DWORD,
|
|
||||||
) -> io::Result<HANDLE> {
|
|
||||||
match unsafe {
|
|
||||||
CreateFileW(
|
|
||||||
file_name.as_ptr(),
|
|
||||||
desired_access,
|
|
||||||
share_mode,
|
|
||||||
ptr::null_mut(),
|
|
||||||
creation_disposition,
|
|
||||||
flags_and_attributes,
|
|
||||||
ptr::null_mut(),
|
|
||||||
)
|
|
||||||
} {
|
|
||||||
INVALID_HANDLE_VALUE => Err(io::Error::last_os_error()),
|
|
||||||
handle => Ok(handle),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn read_file(handle: HANDLE, buffer: &mut [u8]) -> io::Result<DWORD> {
|
|
||||||
let mut ret = 0;
|
|
||||||
//https://www.cnblogs.com/linyilong3/archive/2012/05/03/2480451.html
|
|
||||||
unsafe {
|
|
||||||
let mut ip_overlapped = winapi::um::minwinbase::OVERLAPPED {
|
|
||||||
Internal: 0,
|
|
||||||
InternalHigh: 0,
|
|
||||||
u: Default::default(),
|
|
||||||
hEvent: ptr::null_mut(),
|
|
||||||
};
|
|
||||||
if 0 == ReadFile(
|
|
||||||
handle,
|
|
||||||
buffer.as_mut_ptr() as _,
|
|
||||||
buffer.len() as _,
|
|
||||||
&mut ret,
|
|
||||||
&mut ip_overlapped,
|
|
||||||
) {
|
|
||||||
let e = io::Error::last_os_error();
|
|
||||||
if e.raw_os_error().unwrap_or(0) == ERROR_IO_PENDING as _ {
|
|
||||||
if 0 == GetOverlappedResult(handle, &mut ip_overlapped, &mut ret, 1) {
|
|
||||||
return Err(e);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return Err(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(ret)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn write_file(handle: HANDLE, buffer: &[u8]) -> io::Result<DWORD> {
|
|
||||||
let mut ret = 0;
|
|
||||||
let mut ip_overlapped = winapi::um::minwinbase::OVERLAPPED {
|
|
||||||
Internal: 0,
|
|
||||||
InternalHigh: 0,
|
|
||||||
u: Default::default(),
|
|
||||||
hEvent: ptr::null_mut(),
|
|
||||||
};
|
|
||||||
unsafe {
|
|
||||||
if 0 == WriteFile(
|
|
||||||
handle,
|
|
||||||
buffer.as_ptr() as _,
|
|
||||||
buffer.len() as _,
|
|
||||||
&mut ret,
|
|
||||||
&mut ip_overlapped,
|
|
||||||
) {
|
|
||||||
let e = io::Error::last_os_error();
|
|
||||||
if e.raw_os_error().unwrap_or(0) == ERROR_IO_PENDING as _ {
|
|
||||||
if 0 == GetOverlappedResult(handle, &mut ip_overlapped, &mut ret, 1) {
|
|
||||||
return Err(e);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return Err(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(ret)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn create_device_info_list(guid: &GUID) -> io::Result<HDEVINFO> {
|
|
||||||
match unsafe { SetupDiCreateDeviceInfoList(guid, ptr::null_mut()) } {
|
|
||||||
INVALID_HANDLE_VALUE => Err(io::Error::last_os_error()),
|
|
||||||
devinfo => Ok(devinfo),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_class_devs(guid: &GUID, flags: DWORD) -> io::Result<HDEVINFO> {
|
|
||||||
match unsafe { SetupDiGetClassDevsW(guid, ptr::null(), ptr::null_mut(), flags) } {
|
|
||||||
INVALID_HANDLE_VALUE => Err(io::Error::last_os_error()),
|
|
||||||
devinfo => Ok(devinfo),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn destroy_device_info_list(devinfo: HDEVINFO) -> io::Result<()> {
|
|
||||||
match unsafe { SetupDiDestroyDeviceInfoList(devinfo) } {
|
|
||||||
0 => Err(io::Error::last_os_error()),
|
|
||||||
_ => Ok(()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn class_name_from_guid(guid: &GUID) -> io::Result<Vec<WCHAR>> {
|
|
||||||
let mut class_name = vec![0; 32];
|
|
||||||
|
|
||||||
match unsafe {
|
|
||||||
SetupDiClassNameFromGuidW(
|
|
||||||
guid,
|
|
||||||
class_name.as_mut_ptr(),
|
|
||||||
class_name.len() as _,
|
|
||||||
ptr::null_mut(),
|
|
||||||
)
|
|
||||||
} {
|
|
||||||
0 => Err(io::Error::last_os_error()),
|
|
||||||
_ => Ok(class_name),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn create_device_info(
|
|
||||||
devinfo: HDEVINFO,
|
|
||||||
device_name: &[WCHAR],
|
|
||||||
guid: &GUID,
|
|
||||||
device_description: &[WCHAR],
|
|
||||||
creation_flags: DWORD,
|
|
||||||
) -> io::Result<SP_DEVINFO_DATA> {
|
|
||||||
let mut devinfo_data: SP_DEVINFO_DATA = unsafe { mem::zeroed() };
|
|
||||||
devinfo_data.cbSize = mem::size_of_val(&devinfo_data) as _;
|
|
||||||
|
|
||||||
match unsafe {
|
|
||||||
SetupDiCreateDeviceInfoW(
|
|
||||||
devinfo,
|
|
||||||
device_name.as_ptr(),
|
|
||||||
guid,
|
|
||||||
device_description.as_ptr(),
|
|
||||||
ptr::null_mut(),
|
|
||||||
creation_flags,
|
|
||||||
&mut devinfo_data,
|
|
||||||
)
|
|
||||||
} {
|
|
||||||
0 => Err(io::Error::last_os_error()),
|
|
||||||
_ => Ok(devinfo_data),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_selected_device(devinfo: HDEVINFO, devinfo_data: &SP_DEVINFO_DATA) -> io::Result<()> {
|
|
||||||
match unsafe { SetupDiSetSelectedDevice(devinfo, devinfo_data as *const _ as _) } {
|
|
||||||
0 => Err(io::Error::last_os_error()),
|
|
||||||
_ => Ok(()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_device_registry_property(
|
|
||||||
devinfo: HDEVINFO,
|
|
||||||
devinfo_data: &SP_DEVINFO_DATA,
|
|
||||||
property: DWORD,
|
|
||||||
value: &[WCHAR],
|
|
||||||
) -> io::Result<()> {
|
|
||||||
match unsafe {
|
|
||||||
SetupDiSetDeviceRegistryPropertyW(
|
|
||||||
devinfo,
|
|
||||||
devinfo_data as *const _ as _,
|
|
||||||
property,
|
|
||||||
value.as_ptr() as _,
|
|
||||||
(value.len() * 2) as _,
|
|
||||||
)
|
|
||||||
} {
|
|
||||||
0 => Err(io::Error::last_os_error()),
|
|
||||||
_ => Ok(()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_device_registry_property(
|
|
||||||
devinfo: HDEVINFO,
|
|
||||||
devinfo_data: &SP_DEVINFO_DATA,
|
|
||||||
property: DWORD,
|
|
||||||
) -> io::Result<Vec<WCHAR>> {
|
|
||||||
let mut value = vec![0; 32];
|
|
||||||
|
|
||||||
match unsafe {
|
|
||||||
SetupDiGetDeviceRegistryPropertyW(
|
|
||||||
devinfo,
|
|
||||||
devinfo_data as *const _ as _,
|
|
||||||
property,
|
|
||||||
ptr::null_mut(),
|
|
||||||
value.as_mut_ptr() as _,
|
|
||||||
(value.len() * 2) as _,
|
|
||||||
ptr::null_mut(),
|
|
||||||
)
|
|
||||||
} {
|
|
||||||
0 => Err(io::Error::last_os_error()),
|
|
||||||
_ => Ok(value),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn build_driver_info_list(
|
|
||||||
devinfo: HDEVINFO,
|
|
||||||
devinfo_data: &SP_DEVINFO_DATA,
|
|
||||||
driver_type: DWORD,
|
|
||||||
) -> io::Result<()> {
|
|
||||||
match unsafe { SetupDiBuildDriverInfoList(devinfo, devinfo_data as *const _ as _, driver_type) }
|
|
||||||
{
|
|
||||||
0 => Err(io::Error::last_os_error()),
|
|
||||||
_ => Ok(()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn destroy_driver_info_list(
|
|
||||||
devinfo: HDEVINFO,
|
|
||||||
devinfo_data: &SP_DEVINFO_DATA,
|
|
||||||
driver_type: DWORD,
|
|
||||||
) -> io::Result<()> {
|
|
||||||
match unsafe {
|
|
||||||
SetupDiDestroyDriverInfoList(devinfo, devinfo_data as *const _ as _, driver_type)
|
|
||||||
} {
|
|
||||||
0 => Err(io::Error::last_os_error()),
|
|
||||||
_ => Ok(()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_driver_info_detail(
|
|
||||||
devinfo: HDEVINFO,
|
|
||||||
devinfo_data: &SP_DEVINFO_DATA,
|
|
||||||
drvinfo_data: &SP_DRVINFO_DATA_W,
|
|
||||||
) -> io::Result<SP_DRVINFO_DETAIL_DATA_W2> {
|
|
||||||
let mut drvinfo_detail: SP_DRVINFO_DETAIL_DATA_W2 = unsafe { mem::zeroed() };
|
|
||||||
drvinfo_detail.cbSize = mem::size_of::<SP_DRVINFO_DETAIL_DATA_W>() as _;
|
|
||||||
|
|
||||||
match unsafe {
|
|
||||||
SetupDiGetDriverInfoDetailW(
|
|
||||||
devinfo,
|
|
||||||
devinfo_data as *const _ as _,
|
|
||||||
drvinfo_data as *const _ as _,
|
|
||||||
&mut drvinfo_detail as *mut _ as _,
|
|
||||||
mem::size_of_val(&drvinfo_detail) as _,
|
|
||||||
ptr::null_mut(),
|
|
||||||
)
|
|
||||||
} {
|
|
||||||
0 => Err(io::Error::last_os_error()),
|
|
||||||
_ => Ok(drvinfo_detail),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_selected_driver(
|
|
||||||
devinfo: HDEVINFO,
|
|
||||||
devinfo_data: &SP_DEVINFO_DATA,
|
|
||||||
drvinfo_data: &SP_DRVINFO_DATA_W,
|
|
||||||
) -> io::Result<()> {
|
|
||||||
match unsafe {
|
|
||||||
SetupDiSetSelectedDriverW(
|
|
||||||
devinfo,
|
|
||||||
devinfo_data as *const _ as _,
|
|
||||||
drvinfo_data as *const _ as _,
|
|
||||||
)
|
|
||||||
} {
|
|
||||||
0 => Err(io::Error::last_os_error()),
|
|
||||||
_ => Ok(()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_class_install_params(
|
|
||||||
devinfo: HDEVINFO,
|
|
||||||
devinfo_data: &SP_DEVINFO_DATA,
|
|
||||||
params: &impl Copy,
|
|
||||||
) -> io::Result<()> {
|
|
||||||
match unsafe {
|
|
||||||
SetupDiSetClassInstallParamsW(
|
|
||||||
devinfo,
|
|
||||||
devinfo_data as *const _ as _,
|
|
||||||
params as *const _ as _,
|
|
||||||
mem::size_of_val(params) as _,
|
|
||||||
)
|
|
||||||
} {
|
|
||||||
0 => Err(io::Error::last_os_error()),
|
|
||||||
_ => Ok(()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn call_class_installer(
|
|
||||||
devinfo: HDEVINFO,
|
|
||||||
devinfo_data: &SP_DEVINFO_DATA,
|
|
||||||
install_function: DI_FUNCTION,
|
|
||||||
) -> io::Result<()> {
|
|
||||||
match unsafe {
|
|
||||||
SetupDiCallClassInstaller(install_function, devinfo, devinfo_data as *const _ as _)
|
|
||||||
} {
|
|
||||||
0 => Err(io::Error::last_os_error()),
|
|
||||||
_ => Ok(()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn open_dev_reg_key(
|
|
||||||
devinfo: HDEVINFO,
|
|
||||||
devinfo_data: &SP_DEVINFO_DATA,
|
|
||||||
scope: DWORD,
|
|
||||||
hw_profile: DWORD,
|
|
||||||
key_type: DWORD,
|
|
||||||
sam_desired: REGSAM,
|
|
||||||
) -> io::Result<HKEY> {
|
|
||||||
const INVALID_KEY_VALUE: HKEY = INVALID_HANDLE_VALUE as _;
|
|
||||||
|
|
||||||
match unsafe {
|
|
||||||
SetupDiOpenDevRegKey(
|
|
||||||
devinfo,
|
|
||||||
devinfo_data as *const _ as _,
|
|
||||||
scope,
|
|
||||||
hw_profile,
|
|
||||||
key_type,
|
|
||||||
sam_desired,
|
|
||||||
)
|
|
||||||
} {
|
|
||||||
INVALID_KEY_VALUE => Err(io::Error::last_os_error()),
|
|
||||||
key => Ok(key),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn notify_change_key_value(
|
|
||||||
key: HKEY,
|
|
||||||
watch_subtree: BOOL,
|
|
||||||
notify_filter: DWORD,
|
|
||||||
milliseconds: DWORD,
|
|
||||||
) -> io::Result<()> {
|
|
||||||
let event = match unsafe { CreateEventW(ptr::null_mut(), FALSE, FALSE, ptr::null()) } {
|
|
||||||
INVALID_HANDLE_VALUE => Err(io::Error::last_os_error()),
|
|
||||||
event => Ok(event),
|
|
||||||
}?;
|
|
||||||
|
|
||||||
match unsafe { RegNotifyChangeKeyValue(key, watch_subtree, notify_filter, event, TRUE) } {
|
|
||||||
0 => Ok(()),
|
|
||||||
err => Err(io::Error::from_raw_os_error(err)),
|
|
||||||
}?;
|
|
||||||
|
|
||||||
match unsafe { WaitForSingleObject(event, milliseconds) } {
|
|
||||||
0 => Ok(()),
|
|
||||||
0x102 => Err(io::Error::new(
|
|
||||||
io::ErrorKind::TimedOut,
|
|
||||||
"Registry timed out",
|
|
||||||
)),
|
|
||||||
_ => Err(io::Error::last_os_error()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn enum_driver_info(
|
|
||||||
devinfo: HDEVINFO,
|
|
||||||
devinfo_data: &SP_DEVINFO_DATA,
|
|
||||||
driver_type: DWORD,
|
|
||||||
member_index: DWORD,
|
|
||||||
) -> Option<io::Result<SP_DRVINFO_DATA_W>> {
|
|
||||||
let mut drvinfo_data: SP_DRVINFO_DATA_W = unsafe { mem::zeroed() };
|
|
||||||
drvinfo_data.cbSize = mem::size_of_val(&drvinfo_data) as _;
|
|
||||||
|
|
||||||
match unsafe {
|
|
||||||
SetupDiEnumDriverInfoW(
|
|
||||||
devinfo,
|
|
||||||
devinfo_data as *const _ as _,
|
|
||||||
driver_type,
|
|
||||||
member_index,
|
|
||||||
&mut drvinfo_data,
|
|
||||||
)
|
|
||||||
} {
|
|
||||||
0 if unsafe { GetLastError() == ERROR_NO_MORE_ITEMS } => None,
|
|
||||||
0 => Some(Err(io::Error::last_os_error())),
|
|
||||||
_ => Some(Ok(drvinfo_data)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn enum_device_info(
|
|
||||||
devinfo: HDEVINFO,
|
|
||||||
member_index: DWORD,
|
|
||||||
) -> Option<io::Result<SP_DEVINFO_DATA>> {
|
|
||||||
let mut devinfo_data: SP_DEVINFO_DATA = unsafe { mem::zeroed() };
|
|
||||||
devinfo_data.cbSize = mem::size_of_val(&devinfo_data) as _;
|
|
||||||
|
|
||||||
match unsafe { SetupDiEnumDeviceInfo(devinfo, member_index, &mut devinfo_data) } {
|
|
||||||
0 if unsafe { GetLastError() == ERROR_NO_MORE_ITEMS } => None,
|
|
||||||
0 => Some(Err(io::Error::last_os_error())),
|
|
||||||
_ => Some(Ok(devinfo_data)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn device_io_control(
|
|
||||||
handle: HANDLE,
|
|
||||||
io_control_code: DWORD,
|
|
||||||
in_buffer: &impl Copy,
|
|
||||||
out_buffer: &mut impl Copy,
|
|
||||||
) -> io::Result<()> {
|
|
||||||
let mut junk = 0;
|
|
||||||
|
|
||||||
match unsafe {
|
|
||||||
DeviceIoControl(
|
|
||||||
handle,
|
|
||||||
io_control_code,
|
|
||||||
in_buffer as *const _ as _,
|
|
||||||
mem::size_of_val(in_buffer) as _,
|
|
||||||
out_buffer as *mut _ as _,
|
|
||||||
mem::size_of_val(out_buffer) as _,
|
|
||||||
&mut junk,
|
|
||||||
ptr::null_mut(),
|
|
||||||
)
|
|
||||||
} {
|
|
||||||
0 => Err(io::Error::last_os_error()),
|
|
||||||
_ => Ok(()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
use std::io;
|
|
||||||
use std::os::windows::process::CommandExt;
|
|
||||||
use winapi::shared::minwindef::DWORD;
|
|
||||||
use winapi::um::winbase::CREATE_NO_WINDOW;
|
|
||||||
|
|
||||||
mod check;
|
|
||||||
mod device;
|
|
||||||
mod ffi;
|
|
||||||
mod netsh;
|
|
||||||
mod route;
|
|
||||||
mod tap;
|
|
||||||
mod tun;
|
|
||||||
pub use device::Device;
|
|
||||||
|
|
||||||
/// Encode a string as a utf16 buffer
|
|
||||||
pub fn encode_utf16(string: &str) -> Vec<u16> {
|
|
||||||
use std::iter::once;
|
|
||||||
string.encode_utf16().chain(once(0)).collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn decode_utf16(string: &[u16]) -> String {
|
|
||||||
let end = string.iter().position(|b| *b == 0).unwrap_or(string.len());
|
|
||||||
String::from_utf16_lossy(&string[..end])
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const fn ctl_code(device_type: DWORD, function: DWORD, method: DWORD, access: DWORD) -> DWORD {
|
|
||||||
(device_type << 16) | (access << 14) | (function << 2) | method
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn exe_cmd(cmd: &str) -> io::Result<()> {
|
|
||||||
println!("exe cmd: {}", cmd);
|
|
||||||
let out = std::process::Command::new("cmd")
|
|
||||||
.creation_flags(CREATE_NO_WINDOW)
|
|
||||||
.arg("/C")
|
|
||||||
.arg(&cmd)
|
|
||||||
.output()?;
|
|
||||||
if !out.status.success() {
|
|
||||||
return Err(io::Error::new(
|
|
||||||
io::ErrorKind::Other,
|
|
||||||
format!("cmd={},out={:?}", cmd, String::from_utf8(out.stderr)),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
#![allow(dead_code)]
|
|
||||||
use crate::windows::exe_cmd;
|
|
||||||
use std::io;
|
|
||||||
use std::net::Ipv4Addr;
|
|
||||||
|
|
||||||
/// 设置网卡名称
|
|
||||||
pub fn set_interface_name(old_name: &str, new_name: &str) -> io::Result<()> {
|
|
||||||
let cmd = format!(
|
|
||||||
" netsh interface set interface name={:?} newname={:?}",
|
|
||||||
old_name, new_name
|
|
||||||
);
|
|
||||||
exe_cmd(&cmd)
|
|
||||||
}
|
|
||||||
/// 删除缓存
|
|
||||||
pub fn delete_cache() -> io::Result<()> {
|
|
||||||
//清除缓存
|
|
||||||
let cmd = "netsh interface ip delete destinationcache";
|
|
||||||
exe_cmd(cmd)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 设置网卡ip
|
|
||||||
pub fn set_interface_ip(index: u32, address: &Ipv4Addr, netmask: &Ipv4Addr) -> io::Result<()> {
|
|
||||||
let cmd = format!(
|
|
||||||
"netsh interface ip set address {} static {:?} {:?} ",
|
|
||||||
index, address, netmask,
|
|
||||||
);
|
|
||||||
exe_cmd(&cmd)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_interface_mtu(index: u32, mtu: u32) -> io::Result<()> {
|
|
||||||
let cmd = format!(
|
|
||||||
"netsh interface ipv4 set subinterface {} mtu={} store=persistent",
|
|
||||||
index, mtu
|
|
||||||
);
|
|
||||||
exe_cmd(&cmd)
|
|
||||||
}
|
|
||||||
pub fn set_interface_metric(index: u32, metric: u16) -> io::Result<()> {
|
|
||||||
let cmd = format!(
|
|
||||||
"netsh interface ip set interface {} metric={}",
|
|
||||||
index, metric
|
|
||||||
);
|
|
||||||
exe_cmd(&cmd)
|
|
||||||
}
|
|
||||||
/// 禁用ipv6
|
|
||||||
pub fn disabled_ipv6(index: u32) -> io::Result<()> {
|
|
||||||
let cmd = format!("netsh interface ipv6 set interface {} disabled", index);
|
|
||||||
exe_cmd(&cmd)
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
use std::io;
|
|
||||||
use std::net::Ipv4Addr;
|
|
||||||
|
|
||||||
use crate::windows::exe_cmd;
|
|
||||||
|
|
||||||
/// 添加路由
|
|
||||||
pub fn add_route(
|
|
||||||
index: u32,
|
|
||||||
dest: Ipv4Addr,
|
|
||||||
netmask: Ipv4Addr,
|
|
||||||
gateway: Ipv4Addr,
|
|
||||||
metric: u16,
|
|
||||||
) -> io::Result<()> {
|
|
||||||
let cmd = format!(
|
|
||||||
"route add {:?} mask {:?} {:?} metric {} if {}",
|
|
||||||
dest, netmask, gateway, metric, index
|
|
||||||
);
|
|
||||||
exe_cmd(&cmd)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 删除路由
|
|
||||||
pub fn delete_route(
|
|
||||||
index: u32,
|
|
||||||
dest: Ipv4Addr,
|
|
||||||
netmask: Ipv4Addr,
|
|
||||||
gateway: Ipv4Addr,
|
|
||||||
) -> io::Result<()> {
|
|
||||||
let cmd = format!(
|
|
||||||
"route delete {:?} mask {:?} {:?} if {}",
|
|
||||||
dest, netmask, gateway, index
|
|
||||||
);
|
|
||||||
exe_cmd(&cmd)
|
|
||||||
}
|
|
||||||
@@ -1,185 +0,0 @@
|
|||||||
#![allow(dead_code)]
|
|
||||||
use std::io;
|
|
||||||
use std::net::Ipv4Addr;
|
|
||||||
use winapi::shared::ifdef::NET_LUID;
|
|
||||||
use winapi::shared::minwindef::DWORD;
|
|
||||||
use winapi::um::fileapi::OPEN_EXISTING;
|
|
||||||
use winapi::um::winbase::FILE_FLAG_OVERLAPPED;
|
|
||||||
use winapi::um::winioctl::{FILE_ANY_ACCESS, FILE_DEVICE_UNKNOWN, METHOD_BUFFERED};
|
|
||||||
use winapi::um::winnt::{
|
|
||||||
FILE_ATTRIBUTE_SYSTEM, FILE_SHARE_READ, FILE_SHARE_WRITE, GENERIC_READ, GENERIC_WRITE, HANDLE,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::device::IFace;
|
|
||||||
use crate::packet;
|
|
||||||
use crate::windows::{ctl_code, decode_utf16, encode_utf16, ffi, netsh, route};
|
|
||||||
|
|
||||||
/* Present in 8.1 */
|
|
||||||
const TAP_WIN_IOCTL_GET_MAC: DWORD =
|
|
||||||
ctl_code(FILE_DEVICE_UNKNOWN, 1, METHOD_BUFFERED, FILE_ANY_ACCESS);
|
|
||||||
const TAP_WIN_IOCTL_GET_VERSION: DWORD =
|
|
||||||
ctl_code(FILE_DEVICE_UNKNOWN, 2, METHOD_BUFFERED, FILE_ANY_ACCESS);
|
|
||||||
const TAP_WIN_IOCTL_GET_MTU: DWORD =
|
|
||||||
ctl_code(FILE_DEVICE_UNKNOWN, 3, METHOD_BUFFERED, FILE_ANY_ACCESS);
|
|
||||||
const TAP_WIN_IOCTL_GET_INFO: DWORD =
|
|
||||||
ctl_code(FILE_DEVICE_UNKNOWN, 4, METHOD_BUFFERED, FILE_ANY_ACCESS);
|
|
||||||
const TAP_WIN_IOCTL_CONFIG_POINT_TO_POINT: DWORD =
|
|
||||||
ctl_code(FILE_DEVICE_UNKNOWN, 5, METHOD_BUFFERED, FILE_ANY_ACCESS);
|
|
||||||
const TAP_WIN_IOCTL_SET_MEDIA_STATUS: DWORD =
|
|
||||||
ctl_code(FILE_DEVICE_UNKNOWN, 6, METHOD_BUFFERED, FILE_ANY_ACCESS);
|
|
||||||
const TAP_WIN_IOCTL_CONFIG_DHCP_MASQ: DWORD =
|
|
||||||
ctl_code(FILE_DEVICE_UNKNOWN, 7, METHOD_BUFFERED, FILE_ANY_ACCESS);
|
|
||||||
const TAP_WIN_IOCTL_GET_LOG_LINE: DWORD =
|
|
||||||
ctl_code(FILE_DEVICE_UNKNOWN, 8, METHOD_BUFFERED, FILE_ANY_ACCESS);
|
|
||||||
const TAP_WIN_IOCTL_CONFIG_DHCP_SET_OPT: DWORD =
|
|
||||||
ctl_code(FILE_DEVICE_UNKNOWN, 9, METHOD_BUFFERED, FILE_ANY_ACCESS);
|
|
||||||
/* Added in 8.2 */
|
|
||||||
/* obsoletes TAP_WIN_IOCTL_CONFIG_POINT_TO_POINT */
|
|
||||||
const TAP_WIN_IOCTL_CONFIG_TUN: DWORD =
|
|
||||||
ctl_code(FILE_DEVICE_UNKNOWN, 10, METHOD_BUFFERED, FILE_ANY_ACCESS);
|
|
||||||
|
|
||||||
pub struct Device {
|
|
||||||
handle: HANDLE,
|
|
||||||
index: u32,
|
|
||||||
luid: NET_LUID,
|
|
||||||
mac: [u8; 6],
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl Send for Device {}
|
|
||||||
|
|
||||||
unsafe impl Sync for Device {}
|
|
||||||
|
|
||||||
impl Device {
|
|
||||||
/// 打开设备,设置为TUN模式,激活网卡
|
|
||||||
pub fn new(name: String) -> io::Result<Self> {
|
|
||||||
let luid = ffi::alias_to_luid(&encode_utf16(&name)).map_err(|e| {
|
|
||||||
io::Error::new(e.kind(), format!("alias_to_luid name={},err={:?}", name, e))
|
|
||||||
})?;
|
|
||||||
let guid = ffi::luid_to_guid(&luid)
|
|
||||||
.and_then(|guid| ffi::string_from_guid(&guid))
|
|
||||||
.map_err(|e| {
|
|
||||||
io::Error::new(e.kind(), format!("luid_to_guid name={},err={:?}", name, e))
|
|
||||||
})?;
|
|
||||||
let path = format!(r"\\.\Global\{}.tap", decode_utf16(&guid));
|
|
||||||
let handle = ffi::create_file(
|
|
||||||
&encode_utf16(&path),
|
|
||||||
GENERIC_READ | GENERIC_WRITE,
|
|
||||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
||||||
OPEN_EXISTING,
|
|
||||||
FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED,
|
|
||||||
)
|
|
||||||
.map_err(|e| io::Error::new(e.kind(), format!("tap name={},err={:?}", name, e)))?;
|
|
||||||
|
|
||||||
// ep保存tun网卡的IP地址和掩码
|
|
||||||
// let mut ep = [0;3];
|
|
||||||
// ep[0] = Ipv4Addr::new(10,26,0,11).into();
|
|
||||||
// ep[2] = Ipv4Addr::new(255,255,255,0).into();;
|
|
||||||
// ep[1] = ep[0] & ep[2];
|
|
||||||
// //tun模式收不到ipv4包,原因未知 https://github.com/OpenVPN/tap-windows6/issues/111
|
|
||||||
// ffi::device_io_control(handle, TAP_WIN_IOCTL_CONFIG_TUN, &ep, &mut ()).map_err(
|
|
||||||
// |e| {
|
|
||||||
// io::Error::new(
|
|
||||||
// e.kind(),
|
|
||||||
// format!("TAP_WIN_IOCTL_CONFIG_TUN name={},err={:?}", name_str, e),
|
|
||||||
// )
|
|
||||||
// },
|
|
||||||
// )?;
|
|
||||||
let mut mac = [0u8; 6];
|
|
||||||
ffi::device_io_control(handle, TAP_WIN_IOCTL_GET_MAC, &(), &mut mac)
|
|
||||||
.map_err(|e| {
|
|
||||||
io::Error::new(
|
|
||||||
e.kind(),
|
|
||||||
format!("TAP_WIN_IOCTL_CONFIG_TUN name={},err={:?}", name, e),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.map_err(|e| io::Error::new(e.kind(), format!("TAP_WIN_IOCTL_GET_MAC,err={:?}", e)))?;
|
|
||||||
let index = ffi::luid_to_index(&luid).map(|index| index as u32)?;
|
|
||||||
// 设置网卡跃点
|
|
||||||
if let Err(e) = netsh::set_interface_metric(index, 0) {
|
|
||||||
log::warn!("{:?}", e);
|
|
||||||
}
|
|
||||||
let device = Self {
|
|
||||||
handle,
|
|
||||||
index,
|
|
||||||
luid,
|
|
||||||
mac,
|
|
||||||
};
|
|
||||||
device.enabled(true)?;
|
|
||||||
Ok(device)
|
|
||||||
}
|
|
||||||
fn write_tap(&self, buf: &[u8]) -> io::Result<usize> {
|
|
||||||
ffi::write_file(self.handle, buf).map(|res| res as _)
|
|
||||||
}
|
|
||||||
fn enabled(&self, value: bool) -> io::Result<()> {
|
|
||||||
let status: u32 = if value { 1 } else { 0 };
|
|
||||||
ffi::device_io_control(
|
|
||||||
self.handle,
|
|
||||||
TAP_WIN_IOCTL_SET_MEDIA_STATUS,
|
|
||||||
&status,
|
|
||||||
&mut (),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl IFace for Device {
|
|
||||||
fn version(&self) -> io::Result<String> {
|
|
||||||
let mut version = [0u32; 3];
|
|
||||||
ffi::device_io_control(self.handle, TAP_WIN_IOCTL_GET_VERSION, &(), &mut version)?;
|
|
||||||
Ok(format!("{}.{}.{}", version[0], version[1], version[2]))
|
|
||||||
}
|
|
||||||
fn name(&self) -> io::Result<String> {
|
|
||||||
ffi::luid_to_alias(&self.luid).map(|name| decode_utf16(&name))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn shutdown(&self) -> io::Result<()> {
|
|
||||||
self.enabled(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_ip(&self, address: Ipv4Addr, mask: Ipv4Addr) -> io::Result<()> {
|
|
||||||
netsh::set_interface_ip(self.index, &address, &mask)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn mtu(&self) -> io::Result<u32> {
|
|
||||||
let mut mtu = 0;
|
|
||||||
ffi::device_io_control(self.handle, TAP_WIN_IOCTL_GET_MTU, &(), &mut mtu).map(|_| mtu)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_mtu(&self, value: u32) -> io::Result<()> {
|
|
||||||
netsh::set_interface_mtu(self.index, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn add_route(&self, dest: Ipv4Addr, netmask: Ipv4Addr, metric: u16) -> io::Result<()> {
|
|
||||||
route::add_route(self.index, dest, netmask, Ipv4Addr::UNSPECIFIED, metric)?;
|
|
||||||
netsh::delete_cache()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn delete_route(&self, dest: Ipv4Addr, netmask: Ipv4Addr) -> io::Result<()> {
|
|
||||||
route::delete_route(self.index, dest, netmask, Ipv4Addr::UNSPECIFIED)?;
|
|
||||||
netsh::delete_cache()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
|
|
||||||
packet::read_tap(
|
|
||||||
buf,
|
|
||||||
|eth_buf| ffi::read_file(self.handle, eth_buf).map(|res| res as usize),
|
|
||||||
|eth_buf| ffi::write_file(self.handle, eth_buf).map(|res| res as _),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
|
||||||
// 封装二层数据
|
|
||||||
packet::write_tap(
|
|
||||||
buf,
|
|
||||||
|eth_buf| ffi::write_file(self.handle, eth_buf).map(|res| res as _),
|
|
||||||
&self.mac,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for Device {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
if let Err(e) = ffi::close_handle(self.handle) {
|
|
||||||
log::warn!("close_handle={:?}", e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,363 +0,0 @@
|
|||||||
#![allow(dead_code)]
|
|
||||||
use libloading::Library;
|
|
||||||
use sha2::Digest;
|
|
||||||
use std::io;
|
|
||||||
use std::net::Ipv4Addr;
|
|
||||||
use winapi::um::winbase;
|
|
||||||
use winapi::um::{synchapi, winnt};
|
|
||||||
|
|
||||||
use crate::device::IFace;
|
|
||||||
use crate::windows::decode_utf16;
|
|
||||||
use crate::windows::{encode_utf16, ffi, netsh, route};
|
|
||||||
|
|
||||||
mod packet;
|
|
||||||
mod wintun_log;
|
|
||||||
mod wintun_raw;
|
|
||||||
|
|
||||||
/// The maximum size of wintun's internal ring buffer (in bytes)
|
|
||||||
pub const MAX_RING_CAPACITY: u32 = 0x400_0000;
|
|
||||||
|
|
||||||
/// The minimum size of wintun's internal ring buffer (in bytes)
|
|
||||||
pub const MIN_RING_CAPACITY: u32 = 0x2_0000;
|
|
||||||
|
|
||||||
/// Maximum pool name length including zero terminator
|
|
||||||
pub const MAX_POOL: usize = 256;
|
|
||||||
|
|
||||||
pub struct Device {
|
|
||||||
pub(crate) luid: u64,
|
|
||||||
pub(crate) index: u32,
|
|
||||||
/// The session handle given to us by WintunStartSession
|
|
||||||
pub(crate) session: wintun_raw::WINTUN_SESSION_HANDLE,
|
|
||||||
|
|
||||||
/// Shared dll for required wintun driver functions
|
|
||||||
pub(crate) win_tun: wintun_raw::wintun,
|
|
||||||
|
|
||||||
/// Windows event handle that is signaled by the wintun driver when data becomes available to
|
|
||||||
/// read
|
|
||||||
pub(crate) read_event: winnt::HANDLE,
|
|
||||||
|
|
||||||
/// Windows event handle that is signaled when [`TunSession::shutdown`] is called force blocking
|
|
||||||
/// readers to exit
|
|
||||||
pub(crate) shutdown_event: winnt::HANDLE,
|
|
||||||
|
|
||||||
/// The adapter that owns this session
|
|
||||||
pub(crate) adapter: wintun_raw::WINTUN_ADAPTER_HANDLE,
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl Send for Device {}
|
|
||||||
|
|
||||||
unsafe impl Sync for Device {}
|
|
||||||
|
|
||||||
impl Device {
|
|
||||||
pub fn new(name: String) -> io::Result<Self> {
|
|
||||||
unsafe {
|
|
||||||
let library = match Library::new("wintun.dll") {
|
|
||||||
Ok(library) => library,
|
|
||||||
Err(e) => {
|
|
||||||
return Err(io::Error::new(
|
|
||||||
io::ErrorKind::Other,
|
|
||||||
format!("wintun.dll not found {:?}", e),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let win_tun = match wintun_raw::wintun::from_library(library) {
|
|
||||||
Ok(win_tun) => win_tun,
|
|
||||||
Err(e) => {
|
|
||||||
return Err(io::Error::new(
|
|
||||||
io::ErrorKind::Other,
|
|
||||||
format!("library error {:?} ", e),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let name_utf16 = encode_utf16(&name);
|
|
||||||
if name_utf16.len() > MAX_POOL {
|
|
||||||
return Err(io::Error::new(
|
|
||||||
io::ErrorKind::Other,
|
|
||||||
format!("too long {}:{:?}", MAX_POOL, name),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
wintun_log::set_default_logger_if_unset(&win_tun);
|
|
||||||
if Self::delete_for_name(&win_tun, &name_utf16).is_ok() {
|
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
|
||||||
}
|
|
||||||
let guid_bytes: [u8; 16] = hash_guid(&name);
|
|
||||||
let guid = u128::from_ne_bytes(guid_bytes);
|
|
||||||
//SAFETY: guid is a unique integer so transmuting either all zeroes or the user's preferred
|
|
||||||
//guid to the winapi guid type is safe and will allow the windows kernel to see our GUID
|
|
||||||
|
|
||||||
let guid_struct: wintun_raw::GUID = std::mem::transmute(guid);
|
|
||||||
let guid_ptr = &guid_struct as *const wintun_raw::GUID;
|
|
||||||
|
|
||||||
//SAFETY: the function is loaded from the wintun dll properly, we are providing valid
|
|
||||||
//pointers, and all the strings are correct null terminated UTF-16. This safety rationale
|
|
||||||
//applies for all Wintun* functions below
|
|
||||||
let adapter =
|
|
||||||
win_tun.WintunCreateAdapter(name_utf16.as_ptr(), name_utf16.as_ptr(), guid_ptr);
|
|
||||||
if adapter.is_null() {
|
|
||||||
log::error!("adapter.is_null {:?}", io::Error::last_os_error());
|
|
||||||
return Err(io::Error::new(
|
|
||||||
io::ErrorKind::Other,
|
|
||||||
"Failed to crate adapter",
|
|
||||||
));
|
|
||||||
}
|
|
||||||
// 开启session
|
|
||||||
let session = win_tun.WintunStartSession(adapter, 4 * 1024 * 1024);
|
|
||||||
if session.is_null() {
|
|
||||||
log::error!("session.is_null {:?}", io::Error::last_os_error());
|
|
||||||
return Err(io::Error::new(
|
|
||||||
io::ErrorKind::Other,
|
|
||||||
"WintunStartSession failed",
|
|
||||||
));
|
|
||||||
}
|
|
||||||
//SAFETY: We follow the contract required by CreateEventA. See MSDN
|
|
||||||
//(the pointers are allowed to be null, and 0 is okay for the others)
|
|
||||||
let shutdown_event =
|
|
||||||
synchapi::CreateEventA(std::ptr::null_mut(), 0, 0, std::ptr::null_mut());
|
|
||||||
let read_event = win_tun.WintunGetReadWaitEvent(session) as winnt::HANDLE;
|
|
||||||
let mut luid: wintun_raw::NET_LUID = std::mem::zeroed();
|
|
||||||
win_tun.WintunGetAdapterLUID(adapter, &mut luid as *mut wintun_raw::NET_LUID);
|
|
||||||
let index = ffi::luid_to_index(&std::mem::transmute(luid)).map(|index| index as u32)?;
|
|
||||||
// 设置网卡跃点
|
|
||||||
if let Err(e) = netsh::set_interface_metric(index, 0) {
|
|
||||||
log::warn!("{:?}", e);
|
|
||||||
}
|
|
||||||
Ok(Self {
|
|
||||||
luid: std::mem::transmute(luid),
|
|
||||||
index,
|
|
||||||
session,
|
|
||||||
win_tun,
|
|
||||||
read_event,
|
|
||||||
shutdown_event,
|
|
||||||
adapter,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub unsafe fn delete_for_name(
|
|
||||||
win_tun: &wintun_raw::wintun,
|
|
||||||
name_utf16: &Vec<u16>,
|
|
||||||
) -> io::Result<()> {
|
|
||||||
let adapter = win_tun.WintunOpenAdapter(name_utf16.as_ptr());
|
|
||||||
if adapter.is_null() {
|
|
||||||
log::error!(
|
|
||||||
"delete_for_name adapter.is_null {:?}",
|
|
||||||
io::Error::last_os_error()
|
|
||||||
);
|
|
||||||
return Err(io::Error::new(
|
|
||||||
io::ErrorKind::Other,
|
|
||||||
"Failed to open adapter",
|
|
||||||
));
|
|
||||||
}
|
|
||||||
win_tun.WintunCloseAdapter(adapter);
|
|
||||||
win_tun.WintunDeleteDriver();
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn hash_guid(input: &str) -> [u8; 16] {
|
|
||||||
let mut hasher = sha2::Sha256::new();
|
|
||||||
hasher.update(input.as_bytes());
|
|
||||||
hasher.update(b"VNT");
|
|
||||||
hasher.update(input.as_bytes());
|
|
||||||
hasher.update(b"2024");
|
|
||||||
let hash: [u8; 32] = hasher.finalize().into();
|
|
||||||
hash[..16].try_into().unwrap()
|
|
||||||
}
|
|
||||||
impl IFace for Device {
|
|
||||||
fn version(&self) -> io::Result<String> {
|
|
||||||
let version = unsafe { self.win_tun.WintunGetRunningDriverVersion() };
|
|
||||||
if version == 0 {
|
|
||||||
return Err(io::Error::new(
|
|
||||||
io::ErrorKind::Other,
|
|
||||||
"WintunGetRunningDriverVersion",
|
|
||||||
));
|
|
||||||
} else {
|
|
||||||
Ok(format!("{}.{}", (version >> 16) & 0xFFFF, version & 0xFFFF))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn name(&self) -> io::Result<String> {
|
|
||||||
let luid = self.luid;
|
|
||||||
ffi::luid_to_alias(&unsafe { std::mem::transmute(luid) }).map(|name| decode_utf16(&name))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn shutdown(&self) -> io::Result<()> {
|
|
||||||
unsafe {
|
|
||||||
if winapi::shared::minwindef::TRUE == synchapi::SetEvent(self.shutdown_event) {
|
|
||||||
Ok(())
|
|
||||||
} else {
|
|
||||||
Err(io::Error::last_os_error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_ip(&self, address: Ipv4Addr, mask: Ipv4Addr) -> io::Result<()> {
|
|
||||||
netsh::set_interface_ip(self.index, &address, &mask)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn mtu(&self) -> io::Result<u32> {
|
|
||||||
Err(io::Error::from(io::ErrorKind::Unsupported))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_mtu(&self, value: u32) -> io::Result<()> {
|
|
||||||
netsh::set_interface_mtu(self.index, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn add_route(&self, dest: Ipv4Addr, netmask: Ipv4Addr, metric: u16) -> io::Result<()> {
|
|
||||||
route::add_route(self.index, dest, netmask, Ipv4Addr::UNSPECIFIED, metric)?;
|
|
||||||
netsh::delete_cache()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn delete_route(&self, dest: Ipv4Addr, netmask: Ipv4Addr) -> io::Result<()> {
|
|
||||||
route::delete_route(self.index, dest, netmask, Ipv4Addr::UNSPECIFIED)?;
|
|
||||||
netsh::delete_cache()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
|
|
||||||
let packet = self.receive_blocking()?;
|
|
||||||
let packet = packet.bytes();
|
|
||||||
let len = packet.len();
|
|
||||||
if len > buf.len() {
|
|
||||||
return Err(io::Error::new(io::ErrorKind::InvalidData, "data too long"));
|
|
||||||
}
|
|
||||||
buf[..len].copy_from_slice(packet);
|
|
||||||
Ok(len)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
|
||||||
let mut packet = self.allocate_send_packet(buf.len() as u16)?;
|
|
||||||
packet.bytes_mut().copy_from_slice(buf);
|
|
||||||
self.send_packet(packet);
|
|
||||||
Ok(buf.len())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Device {
|
|
||||||
pub fn try_receive(&self) -> io::Result<Option<packet::TunPacket>> {
|
|
||||||
let mut size = 0u32;
|
|
||||||
|
|
||||||
let bytes_ptr = unsafe {
|
|
||||||
self.win_tun
|
|
||||||
.WintunReceivePacket(self.session, &mut size as *mut u32)
|
|
||||||
};
|
|
||||||
|
|
||||||
debug_assert!(size <= u16::MAX as u32);
|
|
||||||
if bytes_ptr.is_null() {
|
|
||||||
//Wintun returns ERROR_NO_MORE_ITEMS instead of blocking if packets are not available
|
|
||||||
let last_error = unsafe { winapi::um::errhandlingapi::GetLastError() };
|
|
||||||
if last_error == winapi::shared::winerror::ERROR_NO_MORE_ITEMS {
|
|
||||||
Ok(None)
|
|
||||||
} else {
|
|
||||||
Err(io::Error::new(
|
|
||||||
io::ErrorKind::Other,
|
|
||||||
format!("try_receive failed {:?}", io::Error::last_os_error()),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Ok(Some(packet::TunPacket {
|
|
||||||
kind: packet::Kind::ReceivePacket,
|
|
||||||
size: size as usize,
|
|
||||||
//SAFETY: ptr is non null, aligned for u8, and readable for up to size bytes (which
|
|
||||||
//must be less than isize::MAX because bytes is a u16
|
|
||||||
bytes_ptr,
|
|
||||||
tun_device: Some(&self),
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn receive_blocking(&self) -> io::Result<packet::TunPacket> {
|
|
||||||
loop {
|
|
||||||
//Try 16 times to receive without blocking so we don't have to issue a syscall to wait
|
|
||||||
//for the event if packets are being received at a rapid rate
|
|
||||||
for i in 0..20 {
|
|
||||||
match self.try_receive() {
|
|
||||||
Ok(data) => match data {
|
|
||||||
None => {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
Some(packet) => {
|
|
||||||
return Ok(packet);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Err(e) => {
|
|
||||||
if i > 10 {
|
|
||||||
// 某些系统存在错误退出的情况(原因不明),这里尝试忽略部分错误
|
|
||||||
return Err(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//Wait on both the read handle and the shutdown handle so that we stop when requested
|
|
||||||
let handles = [self.read_event, self.shutdown_event];
|
|
||||||
let result = unsafe {
|
|
||||||
//SAFETY: We abide by the requirements of WaitForMultipleObjects, handles is a
|
|
||||||
//pointer to valid, aligned, stack memory
|
|
||||||
synchapi::WaitForMultipleObjects(
|
|
||||||
2,
|
|
||||||
&handles as *const winnt::HANDLE,
|
|
||||||
0,
|
|
||||||
winbase::INFINITE,
|
|
||||||
)
|
|
||||||
};
|
|
||||||
match result {
|
|
||||||
winbase::WAIT_FAILED => {
|
|
||||||
return Err(io::Error::new(io::ErrorKind::Other, "WAIT_FAILED"));
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
if result == winbase::WAIT_OBJECT_0 {
|
|
||||||
//We have data!
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
//Shutdown event triggered
|
|
||||||
return Err(io::Error::new(
|
|
||||||
io::ErrorKind::Other,
|
|
||||||
format!("Shutdown event triggered {}", io::Error::last_os_error()),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn allocate_send_packet(&self, size: u16) -> io::Result<packet::TunPacket> {
|
|
||||||
let bytes_ptr = unsafe {
|
|
||||||
self.win_tun
|
|
||||||
.WintunAllocateSendPacket(self.session, size as u32)
|
|
||||||
};
|
|
||||||
if bytes_ptr.is_null() {
|
|
||||||
Err(io::Error::new(
|
|
||||||
io::ErrorKind::Other,
|
|
||||||
"allocate_send_packet failed",
|
|
||||||
))
|
|
||||||
} else {
|
|
||||||
Ok(packet::TunPacket {
|
|
||||||
kind: packet::Kind::SendPacketPending,
|
|
||||||
size: size as usize,
|
|
||||||
//SAFETY: ptr is non null, aligned for u8, and readable for up to size bytes (which
|
|
||||||
//must be less than isize::MAX because bytes is a u16
|
|
||||||
bytes_ptr,
|
|
||||||
tun_device: None,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn send_packet(&self, mut packet: packet::TunPacket) {
|
|
||||||
assert!(matches!(packet.kind, packet::Kind::SendPacketPending));
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
self.win_tun
|
|
||||||
.WintunSendPacket(self.session, packet.bytes_ptr)
|
|
||||||
};
|
|
||||||
//Mark the packet at sent
|
|
||||||
packet.kind = packet::Kind::SendPacketSent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for Device {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
unsafe {
|
|
||||||
if let Err(e) = ffi::close_handle(self.shutdown_event) {
|
|
||||||
log::warn!("close shutdown_event={:?}", e)
|
|
||||||
}
|
|
||||||
self.win_tun.WintunEndSession(self.session);
|
|
||||||
self.win_tun.WintunCloseAdapter(self.adapter);
|
|
||||||
if winapi::shared::minwindef::FALSE == self.win_tun.WintunDeleteDriver() {
|
|
||||||
log::warn!("WintunDeleteDriver failed {:?}", io::Error::last_os_error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
use crate::windows::tun::Device;
|
|
||||||
|
|
||||||
pub(crate) enum Kind {
|
|
||||||
SendPacketPending,
|
|
||||||
//Send packet type, but not sent yet
|
|
||||||
SendPacketSent,
|
|
||||||
//Send packet type - sent
|
|
||||||
ReceivePacket,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Represents a wintun packet
|
|
||||||
pub struct TunPacket<'a> {
|
|
||||||
pub(crate) kind: Kind,
|
|
||||||
pub(crate) size: usize,
|
|
||||||
pub(crate) bytes_ptr: *const u8,
|
|
||||||
|
|
||||||
//Share ownership of session to prevent the session from being dropped before packets that
|
|
||||||
//belong to it
|
|
||||||
pub(crate) tun_device: Option<&'a Device>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> TunPacket<'a> {
|
|
||||||
/// Returns the bytes this packet holds as &mut.
|
|
||||||
/// The lifetime of the bytes is tied to the lifetime of this packet.
|
|
||||||
pub fn bytes_mut(&mut self) -> &mut [u8] {
|
|
||||||
unsafe { std::slice::from_raw_parts_mut(self.bytes_ptr as *mut u8, self.size) }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns an immutable reference to the bytes this packet holds.
|
|
||||||
/// The lifetime of the bytes is tied to the lifetime of this packet.
|
|
||||||
pub fn bytes(&self) -> &[u8] {
|
|
||||||
unsafe { std::slice::from_raw_parts(self.bytes_ptr, self.size) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Drop for TunPacket<'a> {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
match self.kind {
|
|
||||||
Kind::ReceivePacket => {
|
|
||||||
unsafe {
|
|
||||||
//SAFETY:
|
|
||||||
//
|
|
||||||
// 1. We share ownership of the session therefore it hasn't been dropped yet
|
|
||||||
// 2. Bytes is valid because each packet holds exclusive access to a region of the
|
|
||||||
// ring buffer that the wintun session owns. We return that region of
|
|
||||||
// memory back to wintun here
|
|
||||||
let tun_device = self.tun_device.unwrap();
|
|
||||||
tun_device
|
|
||||||
.win_tun
|
|
||||||
.WintunReleaseReceivePacket(tun_device.session, self.bytes_ptr)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
Kind::SendPacketPending => {
|
|
||||||
//If someone allocates a packet with session.allocate_send_packet() and then it is
|
|
||||||
//dropped without being sent, this will hold up the send queue because wintun expects
|
|
||||||
//that every allocated packet is sent
|
|
||||||
panic!("Packet was never sent!");
|
|
||||||
}
|
|
||||||
Kind::SendPacketSent => {
|
|
||||||
//Nop
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
#![allow(dead_code)]
|
|
||||||
use log::*;
|
|
||||||
|
|
||||||
use crate::windows::tun::wintun_raw;
|
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
|
||||||
use widestring::U16CStr;
|
|
||||||
|
|
||||||
/// Sets the logger wintun will use when logging. Maps to the WintunSetLogger C function
|
|
||||||
pub fn set_logger(win_tun: &wintun_raw::wintun, f: wintun_raw::WINTUN_LOGGER_CALLBACK) {
|
|
||||||
unsafe { win_tun.WintunSetLogger(f) };
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn reset_logger(win_tun: &wintun_raw::wintun) {
|
|
||||||
set_logger(win_tun, None);
|
|
||||||
}
|
|
||||||
|
|
||||||
static SET_LOGGER: AtomicBool = AtomicBool::new(false);
|
|
||||||
|
|
||||||
/// The logger that is active by default. Logs messages to the log crate
|
|
||||||
///
|
|
||||||
/// # Safety
|
|
||||||
/// `message` must be a valid pointer that points to an aligned null terminated UTF-16 string
|
|
||||||
pub unsafe extern "C" fn default_logger(
|
|
||||||
level: wintun_raw::WINTUN_LOGGER_LEVEL,
|
|
||||||
_timestamp: wintun_raw::DWORD64,
|
|
||||||
message: *const wintun_raw::WCHAR,
|
|
||||||
) {
|
|
||||||
//Cant wait for RFC 2585
|
|
||||||
#[allow(unused_unsafe)]
|
|
||||||
//Wintun will always give us a valid UTF16 null termineted string
|
|
||||||
let msg = unsafe { U16CStr::from_ptr_str(message) };
|
|
||||||
let utf8_msg = msg.to_string_lossy();
|
|
||||||
match level {
|
|
||||||
wintun_raw::WINTUN_LOGGER_LEVEL_WINTUN_LOG_INFO => info!("WinTun: {}", utf8_msg),
|
|
||||||
wintun_raw::WINTUN_LOGGER_LEVEL_WINTUN_LOG_WARN => warn!("WinTun: {}", utf8_msg),
|
|
||||||
wintun_raw::WINTUN_LOGGER_LEVEL_WINTUN_LOG_ERR => error!("WinTun: {}", utf8_msg),
|
|
||||||
_ => error!("WinTun: {} (with invalid log level {})", utf8_msg, level),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn set_default_logger_if_unset(win_tun: &wintun_raw::wintun) {
|
|
||||||
if SET_LOGGER
|
|
||||||
.compare_exchange(false, true, Ordering::SeqCst, Ordering::Relaxed)
|
|
||||||
.is_ok()
|
|
||||||
{
|
|
||||||
set_logger(win_tun, Some(default_logger));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,449 +0,0 @@
|
|||||||
#![allow(non_snake_case)]
|
|
||||||
#![allow(non_camel_case_types)]
|
|
||||||
/* automatically generated by rust-bindgen 0.59.1 */
|
|
||||||
#[repr(C)]
|
|
||||||
#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
|
|
||||||
pub struct __BindgenBitfieldUnit<Storage> {
|
|
||||||
storage: Storage,
|
|
||||||
}
|
|
||||||
impl<Storage> __BindgenBitfieldUnit<Storage> {
|
|
||||||
#[inline]
|
|
||||||
pub const fn new(storage: Storage) -> Self {
|
|
||||||
Self { storage }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<Storage> __BindgenBitfieldUnit<Storage>
|
|
||||||
where
|
|
||||||
Storage: AsRef<[u8]> + AsMut<[u8]>,
|
|
||||||
{
|
|
||||||
#[inline]
|
|
||||||
pub fn get_bit(&self, index: usize) -> bool {
|
|
||||||
debug_assert!(index / 8 < self.storage.as_ref().len());
|
|
||||||
let byte_index = index / 8;
|
|
||||||
let byte = self.storage.as_ref()[byte_index];
|
|
||||||
let bit_index = if cfg!(target_endian = "big") {
|
|
||||||
7 - (index % 8)
|
|
||||||
} else {
|
|
||||||
index % 8
|
|
||||||
};
|
|
||||||
let mask = 1 << bit_index;
|
|
||||||
byte & mask == mask
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
pub fn set_bit(&mut self, index: usize, val: bool) {
|
|
||||||
debug_assert!(index / 8 < self.storage.as_ref().len());
|
|
||||||
let byte_index = index / 8;
|
|
||||||
let byte = &mut self.storage.as_mut()[byte_index];
|
|
||||||
let bit_index = if cfg!(target_endian = "big") {
|
|
||||||
7 - (index % 8)
|
|
||||||
} else {
|
|
||||||
index % 8
|
|
||||||
};
|
|
||||||
let mask = 1 << bit_index;
|
|
||||||
if val {
|
|
||||||
*byte |= mask;
|
|
||||||
} else {
|
|
||||||
*byte &= !mask;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 {
|
|
||||||
debug_assert!(bit_width <= 64);
|
|
||||||
debug_assert!(bit_offset / 8 < self.storage.as_ref().len());
|
|
||||||
debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len());
|
|
||||||
let mut val = 0;
|
|
||||||
for i in 0..(bit_width as usize) {
|
|
||||||
if self.get_bit(i + bit_offset) {
|
|
||||||
let index = if cfg!(target_endian = "big") {
|
|
||||||
bit_width as usize - 1 - i
|
|
||||||
} else {
|
|
||||||
i
|
|
||||||
};
|
|
||||||
val |= 1 << index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) {
|
|
||||||
debug_assert!(bit_width <= 64);
|
|
||||||
debug_assert!(bit_offset / 8 < self.storage.as_ref().len());
|
|
||||||
debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len());
|
|
||||||
for i in 0..(bit_width as usize) {
|
|
||||||
let mask = 1 << i;
|
|
||||||
let val_bit_is_set = val & mask == mask;
|
|
||||||
let index = if cfg!(target_endian = "big") {
|
|
||||||
bit_width as usize - 1 - i
|
|
||||||
} else {
|
|
||||||
i
|
|
||||||
};
|
|
||||||
self.set_bit(index + bit_offset, val_bit_is_set);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub type wchar_t = ::std::os::raw::c_ushort;
|
|
||||||
pub type DWORD = ::std::os::raw::c_ulong;
|
|
||||||
pub type BOOL = ::std::os::raw::c_int;
|
|
||||||
pub type BYTE = ::std::os::raw::c_uchar;
|
|
||||||
pub type ULONG64 = ::std::os::raw::c_ulonglong;
|
|
||||||
pub type DWORD64 = ::std::os::raw::c_ulonglong;
|
|
||||||
pub type WCHAR = wchar_t;
|
|
||||||
pub type LPCWSTR = *const WCHAR;
|
|
||||||
pub type HANDLE = *mut ::std::os::raw::c_void;
|
|
||||||
#[repr(C)]
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
|
||||||
pub struct _GUID {
|
|
||||||
pub Data1: ::std::os::raw::c_ulong,
|
|
||||||
pub Data2: ::std::os::raw::c_ushort,
|
|
||||||
pub Data3: ::std::os::raw::c_ushort,
|
|
||||||
pub Data4: [::std::os::raw::c_uchar; 8usize],
|
|
||||||
}
|
|
||||||
#[test]
|
|
||||||
fn bindgen_test_layout__GUID() {
|
|
||||||
assert_eq!(
|
|
||||||
::std::mem::size_of::<_GUID>(),
|
|
||||||
16usize,
|
|
||||||
concat!("Size of: ", stringify!(_GUID))
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
::std::mem::align_of::<_GUID>(),
|
|
||||||
4usize,
|
|
||||||
concat!("Alignment of ", stringify!(_GUID))
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
unsafe { &(*(::std::ptr::null::<_GUID>())).Data1 as *const _ as usize },
|
|
||||||
0usize,
|
|
||||||
concat!(
|
|
||||||
"Offset of field: ",
|
|
||||||
stringify!(_GUID),
|
|
||||||
"::",
|
|
||||||
stringify!(Data1)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
unsafe { &(*(::std::ptr::null::<_GUID>())).Data2 as *const _ as usize },
|
|
||||||
4usize,
|
|
||||||
concat!(
|
|
||||||
"Offset of field: ",
|
|
||||||
stringify!(_GUID),
|
|
||||||
"::",
|
|
||||||
stringify!(Data2)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
unsafe { &(*(::std::ptr::null::<_GUID>())).Data3 as *const _ as usize },
|
|
||||||
6usize,
|
|
||||||
concat!(
|
|
||||||
"Offset of field: ",
|
|
||||||
stringify!(_GUID),
|
|
||||||
"::",
|
|
||||||
stringify!(Data3)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
unsafe { &(*(::std::ptr::null::<_GUID>())).Data4 as *const _ as usize },
|
|
||||||
8usize,
|
|
||||||
concat!(
|
|
||||||
"Offset of field: ",
|
|
||||||
stringify!(_GUID),
|
|
||||||
"::",
|
|
||||||
stringify!(Data4)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
pub type GUID = _GUID;
|
|
||||||
#[repr(C)]
|
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
pub union _NET_LUID_LH {
|
|
||||||
pub Value: ULONG64,
|
|
||||||
pub Info: _NET_LUID_LH__bindgen_ty_1,
|
|
||||||
}
|
|
||||||
#[repr(C)]
|
|
||||||
#[repr(align(8))]
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
|
||||||
pub struct _NET_LUID_LH__bindgen_ty_1 {
|
|
||||||
pub _bitfield_align_1: [u32; 0],
|
|
||||||
pub _bitfield_1: __BindgenBitfieldUnit<[u8; 8usize]>,
|
|
||||||
}
|
|
||||||
#[test]
|
|
||||||
fn bindgen_test_layout__NET_LUID_LH__bindgen_ty_1() {
|
|
||||||
assert_eq!(
|
|
||||||
::std::mem::size_of::<_NET_LUID_LH__bindgen_ty_1>(),
|
|
||||||
8usize,
|
|
||||||
concat!("Size of: ", stringify!(_NET_LUID_LH__bindgen_ty_1))
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
::std::mem::align_of::<_NET_LUID_LH__bindgen_ty_1>(),
|
|
||||||
8usize,
|
|
||||||
concat!("Alignment of ", stringify!(_NET_LUID_LH__bindgen_ty_1))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
impl _NET_LUID_LH__bindgen_ty_1 {
|
|
||||||
#[inline]
|
|
||||||
pub fn Reserved(&self) -> ULONG64 {
|
|
||||||
unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 24u8) as u64) }
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
pub fn set_Reserved(&mut self, val: ULONG64) {
|
|
||||||
unsafe {
|
|
||||||
let val: u64 = ::std::mem::transmute(val);
|
|
||||||
self._bitfield_1.set(0usize, 24u8, val as u64)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
pub fn NetLuidIndex(&self) -> ULONG64 {
|
|
||||||
unsafe { ::std::mem::transmute(self._bitfield_1.get(24usize, 24u8) as u64) }
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
pub fn set_NetLuidIndex(&mut self, val: ULONG64) {
|
|
||||||
unsafe {
|
|
||||||
let val: u64 = ::std::mem::transmute(val);
|
|
||||||
self._bitfield_1.set(24usize, 24u8, val as u64)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
pub fn IfType(&self) -> ULONG64 {
|
|
||||||
unsafe { ::std::mem::transmute(self._bitfield_1.get(48usize, 16u8) as u64) }
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
pub fn set_IfType(&mut self, val: ULONG64) {
|
|
||||||
unsafe {
|
|
||||||
let val: u64 = ::std::mem::transmute(val);
|
|
||||||
self._bitfield_1.set(48usize, 16u8, val as u64)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
pub fn new_bitfield_1(
|
|
||||||
Reserved: ULONG64,
|
|
||||||
NetLuidIndex: ULONG64,
|
|
||||||
IfType: ULONG64,
|
|
||||||
) -> __BindgenBitfieldUnit<[u8; 8usize]> {
|
|
||||||
let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 8usize]> = Default::default();
|
|
||||||
__bindgen_bitfield_unit.set(0usize, 24u8, {
|
|
||||||
let Reserved: u64 = unsafe { ::std::mem::transmute(Reserved) };
|
|
||||||
Reserved as u64
|
|
||||||
});
|
|
||||||
__bindgen_bitfield_unit.set(24usize, 24u8, {
|
|
||||||
let NetLuidIndex: u64 = unsafe { ::std::mem::transmute(NetLuidIndex) };
|
|
||||||
NetLuidIndex as u64
|
|
||||||
});
|
|
||||||
__bindgen_bitfield_unit.set(48usize, 16u8, {
|
|
||||||
let IfType: u64 = unsafe { ::std::mem::transmute(IfType) };
|
|
||||||
IfType as u64
|
|
||||||
});
|
|
||||||
__bindgen_bitfield_unit
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[test]
|
|
||||||
fn bindgen_test_layout__NET_LUID_LH() {
|
|
||||||
assert_eq!(
|
|
||||||
::std::mem::size_of::<_NET_LUID_LH>(),
|
|
||||||
8usize,
|
|
||||||
concat!("Size of: ", stringify!(_NET_LUID_LH))
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
::std::mem::align_of::<_NET_LUID_LH>(),
|
|
||||||
8usize,
|
|
||||||
concat!("Alignment of ", stringify!(_NET_LUID_LH))
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
unsafe { &(*(::std::ptr::null::<_NET_LUID_LH>())).Value as *const _ as usize },
|
|
||||||
0usize,
|
|
||||||
concat!(
|
|
||||||
"Offset of field: ",
|
|
||||||
stringify!(_NET_LUID_LH),
|
|
||||||
"::",
|
|
||||||
stringify!(Value)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
unsafe { &(*(::std::ptr::null::<_NET_LUID_LH>())).Info as *const _ as usize },
|
|
||||||
0usize,
|
|
||||||
concat!(
|
|
||||||
"Offset of field: ",
|
|
||||||
stringify!(_NET_LUID_LH),
|
|
||||||
"::",
|
|
||||||
stringify!(Info)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
pub type NET_LUID_LH = _NET_LUID_LH;
|
|
||||||
pub type NET_LUID = NET_LUID_LH;
|
|
||||||
#[repr(C)]
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
|
||||||
pub struct _WINTUN_ADAPTER {
|
|
||||||
_unused: [u8; 0],
|
|
||||||
}
|
|
||||||
#[doc = " A handle representing Wintun adapter"]
|
|
||||||
pub type WINTUN_ADAPTER_HANDLE = *mut _WINTUN_ADAPTER;
|
|
||||||
#[doc = "< Informational"]
|
|
||||||
pub const WINTUN_LOGGER_LEVEL_WINTUN_LOG_INFO: WINTUN_LOGGER_LEVEL = 0;
|
|
||||||
#[doc = "< Warning"]
|
|
||||||
pub const WINTUN_LOGGER_LEVEL_WINTUN_LOG_WARN: WINTUN_LOGGER_LEVEL = 1;
|
|
||||||
#[doc = "< Error"]
|
|
||||||
pub const WINTUN_LOGGER_LEVEL_WINTUN_LOG_ERR: WINTUN_LOGGER_LEVEL = 2;
|
|
||||||
#[doc = " Determines the level of logging, passed to WINTUN_LOGGER_CALLBACK."]
|
|
||||||
pub type WINTUN_LOGGER_LEVEL = ::std::os::raw::c_int;
|
|
||||||
#[doc = " Called by internal logger to report diagnostic messages"]
|
|
||||||
#[doc = ""]
|
|
||||||
#[doc = " @param Level Message level."]
|
|
||||||
#[doc = ""]
|
|
||||||
#[doc = " @param Timestamp Message timestamp in in 100ns intervals since 1601-01-01 UTC."]
|
|
||||||
#[doc = ""]
|
|
||||||
#[doc = " @param Message Message text."]
|
|
||||||
pub type WINTUN_LOGGER_CALLBACK = ::std::option::Option<
|
|
||||||
unsafe extern "C" fn(Level: WINTUN_LOGGER_LEVEL, Timestamp: DWORD64, Message: LPCWSTR),
|
|
||||||
>;
|
|
||||||
#[repr(C)]
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
|
||||||
pub struct _TUN_SESSION {
|
|
||||||
_unused: [u8; 0],
|
|
||||||
}
|
|
||||||
#[doc = " A handle representing Wintun session"]
|
|
||||||
pub type WINTUN_SESSION_HANDLE = *mut _TUN_SESSION;
|
|
||||||
extern crate libloading;
|
|
||||||
pub struct wintun {
|
|
||||||
__library: ::libloading::Library,
|
|
||||||
pub WintunCreateAdapter: unsafe extern "C" fn(
|
|
||||||
arg1: LPCWSTR,
|
|
||||||
arg2: LPCWSTR,
|
|
||||||
arg3: *const GUID,
|
|
||||||
) -> WINTUN_ADAPTER_HANDLE,
|
|
||||||
pub WintunCloseAdapter: unsafe extern "C" fn(arg1: WINTUN_ADAPTER_HANDLE),
|
|
||||||
pub WintunOpenAdapter: unsafe extern "C" fn(arg1: LPCWSTR) -> WINTUN_ADAPTER_HANDLE,
|
|
||||||
pub WintunGetAdapterLUID:
|
|
||||||
unsafe extern "C" fn(arg1: WINTUN_ADAPTER_HANDLE, arg2: *mut NET_LUID),
|
|
||||||
pub WintunGetRunningDriverVersion: unsafe extern "C" fn() -> DWORD,
|
|
||||||
pub WintunDeleteDriver: unsafe extern "C" fn() -> BOOL,
|
|
||||||
pub WintunSetLogger: unsafe extern "C" fn(arg1: WINTUN_LOGGER_CALLBACK),
|
|
||||||
pub WintunStartSession:
|
|
||||||
unsafe extern "C" fn(arg1: WINTUN_ADAPTER_HANDLE, arg2: DWORD) -> WINTUN_SESSION_HANDLE,
|
|
||||||
pub WintunEndSession: unsafe extern "C" fn(arg1: WINTUN_SESSION_HANDLE),
|
|
||||||
pub WintunGetReadWaitEvent: unsafe extern "C" fn(arg1: WINTUN_SESSION_HANDLE) -> HANDLE,
|
|
||||||
pub WintunReceivePacket:
|
|
||||||
unsafe extern "C" fn(arg1: WINTUN_SESSION_HANDLE, arg2: *mut DWORD) -> *mut BYTE,
|
|
||||||
pub WintunReleaseReceivePacket:
|
|
||||||
unsafe extern "C" fn(arg1: WINTUN_SESSION_HANDLE, arg2: *const BYTE),
|
|
||||||
pub WintunAllocateSendPacket:
|
|
||||||
unsafe extern "C" fn(arg1: WINTUN_SESSION_HANDLE, arg2: DWORD) -> *mut BYTE,
|
|
||||||
pub WintunSendPacket: unsafe extern "C" fn(arg1: WINTUN_SESSION_HANDLE, arg2: *const BYTE),
|
|
||||||
}
|
|
||||||
impl wintun {
|
|
||||||
pub unsafe fn new<P>(path: P) -> Result<Self, ::libloading::Error>
|
|
||||||
where
|
|
||||||
P: AsRef<::std::ffi::OsStr>,
|
|
||||||
{
|
|
||||||
let library = ::libloading::Library::new(path)?;
|
|
||||||
Self::from_library(library)
|
|
||||||
}
|
|
||||||
pub unsafe fn from_library<L>(library: L) -> Result<Self, ::libloading::Error>
|
|
||||||
where
|
|
||||||
L: Into<::libloading::Library>,
|
|
||||||
{
|
|
||||||
let __library = library.into();
|
|
||||||
let WintunCreateAdapter = __library.get(b"WintunCreateAdapter\0").map(|sym| *sym)?;
|
|
||||||
let WintunCloseAdapter = __library.get(b"WintunCloseAdapter\0").map(|sym| *sym)?;
|
|
||||||
let WintunOpenAdapter = __library.get(b"WintunOpenAdapter\0").map(|sym| *sym)?;
|
|
||||||
let WintunGetAdapterLUID = __library.get(b"WintunGetAdapterLUID\0").map(|sym| *sym)?;
|
|
||||||
let WintunGetRunningDriverVersion = __library
|
|
||||||
.get(b"WintunGetRunningDriverVersion\0")
|
|
||||||
.map(|sym| *sym)?;
|
|
||||||
let WintunDeleteDriver = __library.get(b"WintunDeleteDriver\0").map(|sym| *sym)?;
|
|
||||||
let WintunSetLogger = __library.get(b"WintunSetLogger\0").map(|sym| *sym)?;
|
|
||||||
let WintunStartSession = __library.get(b"WintunStartSession\0").map(|sym| *sym)?;
|
|
||||||
let WintunEndSession = __library.get(b"WintunEndSession\0").map(|sym| *sym)?;
|
|
||||||
let WintunGetReadWaitEvent = __library.get(b"WintunGetReadWaitEvent\0").map(|sym| *sym)?;
|
|
||||||
let WintunReceivePacket = __library.get(b"WintunReceivePacket\0").map(|sym| *sym)?;
|
|
||||||
let WintunReleaseReceivePacket = __library
|
|
||||||
.get(b"WintunReleaseReceivePacket\0")
|
|
||||||
.map(|sym| *sym)?;
|
|
||||||
let WintunAllocateSendPacket = __library
|
|
||||||
.get(b"WintunAllocateSendPacket\0")
|
|
||||||
.map(|sym| *sym)?;
|
|
||||||
let WintunSendPacket = __library.get(b"WintunSendPacket\0").map(|sym| *sym)?;
|
|
||||||
Ok(wintun {
|
|
||||||
__library,
|
|
||||||
WintunCreateAdapter,
|
|
||||||
WintunCloseAdapter,
|
|
||||||
WintunOpenAdapter,
|
|
||||||
WintunGetAdapterLUID,
|
|
||||||
WintunGetRunningDriverVersion,
|
|
||||||
WintunDeleteDriver,
|
|
||||||
WintunSetLogger,
|
|
||||||
WintunStartSession,
|
|
||||||
WintunEndSession,
|
|
||||||
WintunGetReadWaitEvent,
|
|
||||||
WintunReceivePacket,
|
|
||||||
WintunReleaseReceivePacket,
|
|
||||||
WintunAllocateSendPacket,
|
|
||||||
WintunSendPacket,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
pub unsafe fn WintunCreateAdapter(
|
|
||||||
&self,
|
|
||||||
arg1: LPCWSTR,
|
|
||||||
arg2: LPCWSTR,
|
|
||||||
arg3: *const GUID,
|
|
||||||
) -> WINTUN_ADAPTER_HANDLE {
|
|
||||||
(self.WintunCreateAdapter)(arg1, arg2, arg3)
|
|
||||||
}
|
|
||||||
pub unsafe fn WintunCloseAdapter(&self, arg1: WINTUN_ADAPTER_HANDLE) -> () {
|
|
||||||
(self.WintunCloseAdapter)(arg1)
|
|
||||||
}
|
|
||||||
pub unsafe fn WintunOpenAdapter(&self, arg1: LPCWSTR) -> WINTUN_ADAPTER_HANDLE {
|
|
||||||
(self.WintunOpenAdapter)(arg1)
|
|
||||||
}
|
|
||||||
pub unsafe fn WintunGetAdapterLUID(
|
|
||||||
&self,
|
|
||||||
arg1: WINTUN_ADAPTER_HANDLE,
|
|
||||||
arg2: *mut NET_LUID,
|
|
||||||
) -> () {
|
|
||||||
(self.WintunGetAdapterLUID)(arg1, arg2)
|
|
||||||
}
|
|
||||||
pub unsafe fn WintunGetRunningDriverVersion(&self) -> DWORD {
|
|
||||||
(self.WintunGetRunningDriverVersion)()
|
|
||||||
}
|
|
||||||
pub unsafe fn WintunDeleteDriver(&self) -> BOOL {
|
|
||||||
(self.WintunDeleteDriver)()
|
|
||||||
}
|
|
||||||
pub unsafe fn WintunSetLogger(&self, arg1: WINTUN_LOGGER_CALLBACK) -> () {
|
|
||||||
(self.WintunSetLogger)(arg1)
|
|
||||||
}
|
|
||||||
pub unsafe fn WintunStartSession(
|
|
||||||
&self,
|
|
||||||
arg1: WINTUN_ADAPTER_HANDLE,
|
|
||||||
arg2: DWORD,
|
|
||||||
) -> WINTUN_SESSION_HANDLE {
|
|
||||||
(self.WintunStartSession)(arg1, arg2)
|
|
||||||
}
|
|
||||||
pub unsafe fn WintunEndSession(&self, arg1: WINTUN_SESSION_HANDLE) -> () {
|
|
||||||
(self.WintunEndSession)(arg1)
|
|
||||||
}
|
|
||||||
pub unsafe fn WintunGetReadWaitEvent(&self, arg1: WINTUN_SESSION_HANDLE) -> HANDLE {
|
|
||||||
(self.WintunGetReadWaitEvent)(arg1)
|
|
||||||
}
|
|
||||||
pub unsafe fn WintunReceivePacket(
|
|
||||||
&self,
|
|
||||||
arg1: WINTUN_SESSION_HANDLE,
|
|
||||||
arg2: *mut DWORD,
|
|
||||||
) -> *mut BYTE {
|
|
||||||
(self.WintunReceivePacket)(arg1, arg2)
|
|
||||||
}
|
|
||||||
pub unsafe fn WintunReleaseReceivePacket(
|
|
||||||
&self,
|
|
||||||
arg1: WINTUN_SESSION_HANDLE,
|
|
||||||
arg2: *const BYTE,
|
|
||||||
) -> () {
|
|
||||||
(self.WintunReleaseReceivePacket)(arg1, arg2)
|
|
||||||
}
|
|
||||||
pub unsafe fn WintunAllocateSendPacket(
|
|
||||||
&self,
|
|
||||||
arg1: WINTUN_SESSION_HANDLE,
|
|
||||||
arg2: DWORD,
|
|
||||||
) -> *mut BYTE {
|
|
||||||
(self.WintunAllocateSendPacket)(arg1, arg2)
|
|
||||||
}
|
|
||||||
pub unsafe fn WintunSendPacket(&self, arg1: WINTUN_SESSION_HANDLE, arg2: *const BYTE) -> () {
|
|
||||||
(self.WintunSendPacket)(arg1, arg2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user