mirror of
https://github.com/2dust/AndroidLibXrayLite.git
synced 2025-06-30 15:19:51 +00:00
Compare commits
87 commits
Author | SHA1 | Date | |
---|---|---|---|
|
8ad3e1ddf1 | ||
|
22f3e73a78 | ||
|
4de15a6c8d | ||
|
a031a553f6 | ||
|
ddcaecad0a | ||
|
c8b2ac1762 | ||
|
5cdcbc611f | ||
|
ae953fdc4d | ||
|
443ae5f577 | ||
|
bafb45ffcf | ||
|
52f9e06b67 | ||
|
fd5117ab47 | ||
|
c53ff63a3b | ||
|
6796ffc6ee | ||
|
08aa01a2c2 | ||
|
e01192ac83 | ||
|
a9226a4eb2 | ||
|
d18ff82b49 | ||
|
9e25db2025 | ||
|
6ea7a2636a | ||
|
2715a3b110 | ||
|
76b472eb98 | ||
|
74b37729bd | ||
|
6f650d49f3 | ||
|
acb16186b2 | ||
|
759e3e7232 | ||
|
d56745bc86 | ||
|
4ec3c7e177 | ||
|
d3d5265560 | ||
|
e1e7f75d07 | ||
|
c8a6ca7c5e | ||
|
d10cf1a43f | ||
|
08c4a038f0 | ||
|
36f046e27b | ||
|
5644ebf958 | ||
|
ec529ceeef | ||
|
e53f4722b6 | ||
|
fc38247501 | ||
|
eff055be11 | ||
|
052a33d204 | ||
|
19486878e5 | ||
|
c9eee86ef1 | ||
|
68cb3b4f5e | ||
|
0614b2c9ad | ||
|
cf8224cbd6 | ||
|
e738d44233 | ||
|
412ae9774c | ||
|
c60679bf4b | ||
|
ff2b76413d | ||
|
78e06f32b4 | ||
|
49bc025af2 | ||
|
784d91899e | ||
|
afcc3ff300 | ||
|
d996c70876 | ||
|
6a8fd8fee2 | ||
|
90bd5ee711 | ||
|
0b8751b791 | ||
|
664c3892e2 | ||
|
df181a3065 | ||
|
012e75fc36 | ||
|
0184340173 | ||
|
33038b98b3 | ||
|
4a801c73dc | ||
|
3f8c1910e3 | ||
|
b5adf2c15e | ||
|
e7bd5d0062 | ||
|
bba66dc9f1 | ||
|
afe477fb5e | ||
|
4fef7610ff | ||
|
3b880ca10a | ||
|
436d27a6e8 | ||
|
d0a1b5050b | ||
|
30626d4ee1 | ||
|
7ed07f5176 | ||
|
dbfe1c9147 | ||
|
c5f529acde | ||
|
dd91790cf6 | ||
|
f873bc86a8 | ||
|
6da0067cc1 | ||
|
ae44454536 | ||
|
2fce82850b | ||
|
97ef211afc | ||
|
3ae0e86a1c | ||
|
2ea2f18a99 | ||
|
50da838485 | ||
|
43cde7addc | ||
|
b0a4e81a6c |
12 changed files with 65735 additions and 18826 deletions
57
.github/workflows/main.yml
vendored
57
.github/workflows/main.yml
vendored
|
@ -4,43 +4,46 @@ on:
|
|||
workflow_dispatch:
|
||||
inputs:
|
||||
release_tag:
|
||||
required: true
|
||||
required: false
|
||||
type: string
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
uses: actions/checkout@v4.2.2
|
||||
|
||||
- name: Setup Golang
|
||||
uses: actions/setup-go@v4
|
||||
uses: actions/setup-go@v5.4.0
|
||||
with:
|
||||
go-version-file: 'go.mod'
|
||||
|
||||
- name: Setup JDK
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: 17
|
||||
distribution: 'temurin'
|
||||
|
||||
- name: Setup Android SDK Tools
|
||||
uses: android-actions/setup-android@v3.2.0
|
||||
with:
|
||||
cmdline-tools-version: 10406996
|
||||
|
||||
- name: Setup Android NDK
|
||||
uses: nttld/setup-ndk@v1.4.2
|
||||
with:
|
||||
ndk-version: 'r26b'
|
||||
link-to-sdk: true
|
||||
- name: Setup Go Mobile
|
||||
- name: Install gomobile
|
||||
run: |
|
||||
go install golang.org/x/mobile/cmd/gomobile@latest
|
||||
export PATH=$PATH:~/go/bin
|
||||
|
||||
- name: Setup Android SDK
|
||||
uses: android-actions/setup-android@v3.2.0
|
||||
with:
|
||||
log-accepted-android-sdk-licenses: false
|
||||
cmdline-tools-version: '12266719'
|
||||
packages: 'platforms;android-35 build-tools;35.0.0 platform-tools'
|
||||
|
||||
- name: Install NDK
|
||||
run: |
|
||||
echo "y" | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager \
|
||||
--channel=3 \
|
||||
--install "ndk;29.0.13113456"
|
||||
echo "NDK_HOME=$ANDROID_HOME/ndk/29.0.13113456" >> $GITHUB_ENV
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
mkdir -p assets data
|
||||
|
@ -48,8 +51,18 @@ jobs:
|
|||
cp -v data/*.dat assets/
|
||||
gomobile init
|
||||
go mod tidy
|
||||
gomobile bind -v -androidapi 19 -ldflags='-s -w' ./
|
||||
gomobile bind -v -androidapi 21 -trimpath -ldflags='-s -w -buildid=' ./
|
||||
|
||||
- name: Upload build artifacts
|
||||
if: github.event.inputs.release_tag == ''
|
||||
uses: actions/upload-artifact@v4.6.2
|
||||
with:
|
||||
name: libv2ray
|
||||
path: |
|
||||
${{ github.workspace }}/libv2ray*r
|
||||
|
||||
- name: Upload AndroidLibXrayLite to release
|
||||
if: github.event.inputs.release_tag != ''
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
with:
|
||||
file: ./libv2ray*r
|
||||
|
|
86
.github/workflows/tidy.yml
vendored
Normal file
86
.github/workflows/tidy.yml
vendored
Normal file
|
@ -0,0 +1,86 @@
|
|||
name: Check and Update xray-core
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 0 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
update:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout our repository
|
||||
uses: actions/checkout@v4.2.2
|
||||
with:
|
||||
fetch-depth: '0'
|
||||
|
||||
- name: Fetch latest release tag from external repository
|
||||
id: fetch-release
|
||||
run: |
|
||||
EXTERNAL_REPO="XTLS/Xray-core"
|
||||
LATEST_TAG=$(curl -s https://api.github.com/repos/$EXTERNAL_REPO/tags | jq -r '.[0]')
|
||||
LATEST_TAG_NAME=$(echo $LATEST_TAG | jq -r .name)
|
||||
LATEST_TAG_SHA=$(echo $LATEST_TAG | jq -r .commit.sha)
|
||||
echo "Latest tag from external repo: $LATEST_TAG_NAME"
|
||||
echo "LATEST_TAG_NAME=$LATEST_TAG_NAME" >> $GITHUB_ENV
|
||||
echo "LATEST_TAG_SHA=$LATEST_TAG_SHA" >> $GITHUB_ENV
|
||||
|
||||
- name: Fetch current repository release tag
|
||||
id: fetch-current-tag
|
||||
run: |
|
||||
CURRENT_TAG_NAME=$(git describe --tags --abbrev=0)
|
||||
echo "Current tag in this repo: $CURRENT_TAG_NAME"
|
||||
echo "CURRENT_TAG_NAME=$CURRENT_TAG_NAME" >> $GITHUB_ENV
|
||||
|
||||
- name: Compare tags
|
||||
id: compare-tags
|
||||
run: |
|
||||
if [ "$LATEST_TAG_NAME" != "$CURRENT_TAG_NAME" ]; then
|
||||
if [ "$(printf '%s\n' "$LATEST_TAG_NAME" "$CURRENT_TAG_NAME" | sort -V | tail -n1)" == "$CURRENT_TAG_NAME" ]; then
|
||||
echo "Upstream LATEST_TAG_NAME less than the CURRENT_TAG_NAME, no update needed."
|
||||
else
|
||||
echo "Tags are different. Updating..."
|
||||
echo "needs_update=true" >> $GITHUB_ENV
|
||||
fi
|
||||
else
|
||||
echo "Tags are the same. No update needed."
|
||||
echo "needs_update=false" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: Setup Golang
|
||||
if: env.needs_update == 'true'
|
||||
uses: actions/setup-go@v5.4.0
|
||||
with:
|
||||
go-version: 'stable'
|
||||
|
||||
- name: Update and commit changes
|
||||
if: env.needs_update == 'true'
|
||||
run: |
|
||||
go get -u
|
||||
go get github.com/xtls/xray-core@${{ env.LATEST_TAG_SHA }}
|
||||
go get gvisor.dev/gvisor@go
|
||||
go get github.com/OmarTariq612/goech@v0.0.0-20240405204721-8e2e1dafd3a0
|
||||
go mod tidy -v
|
||||
git diff
|
||||
|
||||
- name: Commit and push changes
|
||||
id: auto-commit-action
|
||||
if: env.needs_update == 'true'
|
||||
uses: stefanzweifel/git-auto-commit-action@v5.1.0
|
||||
with:
|
||||
commit_message: Updating xray-core to ${{ env.LATEST_TAG_NAME }} ${{ env.LATEST_TAG_SHA }}
|
||||
tagging_message: ${{ env.LATEST_TAG_NAME }}
|
||||
|
||||
- name: Trigger build
|
||||
if: env.needs_update == 'true' && steps.auto-commit-action.outputs.changes_detected == 'true'
|
||||
run: |
|
||||
curl -X POST \
|
||||
-H "Accept: application/vnd.github.v3+json" \
|
||||
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
|
||||
https://api.github.com/repos/${{ github.repository }}/actions/workflows/main.yml/dispatches \
|
||||
-d "{
|
||||
\"ref\": \"main\",
|
||||
\"inputs\": {
|
||||
\"release_tag\": \"${{ env.LATEST_TAG_NAME }}\"
|
||||
}
|
||||
}"
|
39
.gitignore
vendored
39
.gitignore
vendored
|
@ -1,9 +1,44 @@
|
|||
.vscode
|
||||
# Ignore editor directories and files
|
||||
.idea/
|
||||
.vscode/
|
||||
|
||||
# Ignore Gradle files
|
||||
gradle/build.gradle
|
||||
|
||||
# Ignore Go generated files
|
||||
*.pb.go
|
||||
binary*.go
|
||||
conf/demo/
|
||||
|
||||
# Ignore configuration and demo directories
|
||||
conf/demo/
|
||||
demo/
|
||||
|
||||
# Ignore asset files
|
||||
assets/
|
||||
|
||||
# Ignore V2Ray library files
|
||||
libv2ray*.[a|j]ar
|
||||
|
||||
# Ignore binary files
|
||||
*.exe
|
||||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
|
||||
# Ignore backup and temporary files
|
||||
*~
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# Ignore build and log directories
|
||||
build/
|
||||
logs/
|
||||
|
||||
# Ignore macOS files
|
||||
.DS_Store
|
||||
|
||||
# Ignore Node.js dependencies
|
||||
node_modules/
|
||||
|
||||
# Ignore Go vendor dependencies
|
||||
vendor/
|
||||
|
|
|
@ -10,4 +10,4 @@
|
|||
1. `git clone [repo] && cd AndroidLibXrayLite`
|
||||
2. `gomobile init`
|
||||
3. `go mod tidy -v`
|
||||
4. `gomobile bind -v -androidapi 19 -ldflags='-s -w' ./`
|
||||
4. `gomobile bind -v -androidapi 21 -ldflags='-s -w' ./`
|
||||
|
|
BIN
assets/geoip.dat
BIN
assets/geoip.dat
Binary file not shown.
82921
assets/geosite.dat
82921
assets/geosite.dat
File diff suppressed because one or more lines are too long
|
@ -7,75 +7,33 @@ set -o nounset
|
|||
# Set magic variables for current file & dir
|
||||
__dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
__file="${__dir}/$(basename "${BASH_SOURCE[0]}")"
|
||||
__base="$(basename ${__file} .sh)"
|
||||
__base="$(basename "${__file}" .sh)"
|
||||
|
||||
DATADIR="${__dir}/data"
|
||||
|
||||
|
||||
DATADIR=${__dir}/data
|
||||
|
||||
compile_dat () {
|
||||
local TMPDIR=$(mktemp -d)
|
||||
|
||||
trap 'echo -e "Aborted, error $? in command: $BASH_COMMAND"; rm -rf $TMPDIR; trap ERR; exit 1' ERR
|
||||
|
||||
local GEOSITE=${GOPATH}/src/github.com/v2ray/domain-list-community
|
||||
if [[ -d ${GEOSITE} ]]; then
|
||||
cd ${GEOSITE} && git pull
|
||||
else
|
||||
mkdir -p ${GEOSITE}
|
||||
cd ${GEOSITE} && git clone https://github.com/v2ray/domain-list-community.git .
|
||||
fi
|
||||
go run main.go
|
||||
|
||||
if [[ -e dlc.dat ]]; then
|
||||
rm -f $DATADIR/geosite.dat
|
||||
mv dlc.dat $DATADIR/geosite.dat
|
||||
echo "----------> geosite.dat updated."
|
||||
else
|
||||
echo "----------> geosite.dat failed to update."
|
||||
fi
|
||||
|
||||
|
||||
if [[ ! -x $GOPATH/bin/geoip ]]; then
|
||||
go get -v -u github.com/v2ray/geoip
|
||||
fi
|
||||
|
||||
cd $TMPDIR
|
||||
curl -L -O http://geolite.maxmind.com/download/geoip/database/GeoLite2-Country-CSV.zip
|
||||
unzip -q GeoLite2-Country-CSV.zip
|
||||
mkdir geoip && find . -name '*.csv' -exec mv -t ./geoip {} +
|
||||
$GOPATH/bin/geoip \
|
||||
--country=./geoip/GeoLite2-Country-Locations-en.csv \
|
||||
--ipv4=./geoip/GeoLite2-Country-Blocks-IPv4.csv \
|
||||
--ipv6=./geoip/GeoLite2-Country-Blocks-IPv6.csv
|
||||
|
||||
if [[ -e geoip.dat ]]; then
|
||||
rm -f $DATADIR/geoip.dat
|
||||
mv ./geoip.dat $DATADIR/geoip.dat
|
||||
echo "----------> geoip.dat updated."
|
||||
else
|
||||
echo "----------> geoip.dat failed to update."
|
||||
fi
|
||||
trap ERR
|
||||
return 0
|
||||
# Check for required dependencies
|
||||
check_dependencies() {
|
||||
command -v jq >/dev/null 2>&1 || { echo >&2 "jq is required but it's not installed. Aborting."; exit 1; }
|
||||
command -v go >/dev/null 2>&1 || { echo >&2 "Go is required but it's not installed. Aborting."; exit 1; }
|
||||
}
|
||||
|
||||
|
||||
# Download data function
|
||||
download_dat() {
|
||||
wget -qO - https://api.github.com/repos/v2ray/geoip/releases/latest \
|
||||
| grep browser_download_url | cut -d '"' -f 4 \
|
||||
| wget -i - -O $DATADIR/geoip.dat
|
||||
echo "Downloading geoip.dat..."
|
||||
curl -sL https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat -o "$DATADIR/geoip.dat"
|
||||
|
||||
wget -qO - https://api.github.com/repos/v2ray/domain-list-community/releases/latest \
|
||||
| grep browser_download_url | cut -d '"' -f 4 \
|
||||
| wget -i - -O $DATADIR/geosite.dat
|
||||
echo "Downloading geosite.dat..."
|
||||
curl -sL https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat -o "$DATADIR/geosite.dat"
|
||||
}
|
||||
|
||||
ACTION="${1:-}"
|
||||
if [[ -z $ACTION ]]; then
|
||||
ACTION=download
|
||||
fi
|
||||
# Main execution logic
|
||||
ACTION="${1:-download}"
|
||||
|
||||
check_dependencies
|
||||
|
||||
case $ACTION in
|
||||
"download") download_dat ;;
|
||||
"compile") compile_dat;;
|
||||
*) echo "Invalid action: $ACTION" ; exit 1 ;;
|
||||
esac
|
||||
|
|
80
go.mod
80
go.mod
|
@ -1,54 +1,56 @@
|
|||
module github.com/2dust/AndroidLibXrayLite
|
||||
|
||||
go 1.22.2
|
||||
go 1.24.3
|
||||
|
||||
require (
|
||||
github.com/xtls/xray-core v1.8.11
|
||||
golang.org/x/mobile v0.0.0-20240506190922-a1a533f289d3
|
||||
golang.org/x/sys v0.18.0
|
||||
github.com/xtls/xray-core v1.250516.1-0.20250608135303-fbae89d017ae
|
||||
golang.org/x/mobile v0.0.0-20250606033058-a2a15c67f36f
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/andybalholm/brotli v1.1.0 // indirect
|
||||
github.com/cloudflare/circl v1.3.7 // indirect
|
||||
github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140 // indirect
|
||||
github.com/francoispqt/gojay v1.2.13 // indirect
|
||||
github.com/OmarTariq612/goech v0.0.0-20240405204721-8e2e1dafd3a0 // indirect
|
||||
github.com/andybalholm/brotli v1.1.1 // indirect
|
||||
github.com/cloudflare/circl v1.6.1 // indirect
|
||||
github.com/dgryski/go-metro v0.0.0-20250106013310-edb8663e5e33 // indirect
|
||||
github.com/ghodss/yaml v1.0.1-0.20220118164431-d8423dcdf344 // indirect
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/google/btree v1.1.2 // indirect
|
||||
github.com/google/pprof v0.0.0-20240227163752-401108e1b7e7 // indirect
|
||||
github.com/gorilla/websocket v1.5.1 // indirect
|
||||
github.com/klauspost/compress v1.17.7 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
|
||||
github.com/onsi/ginkgo/v2 v2.16.0 // indirect
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
|
||||
github.com/google/btree v1.1.3 // indirect
|
||||
github.com/google/pprof v0.0.0-20250607225305-033d6d78b36a // indirect
|
||||
github.com/gorilla/websocket v1.5.3 // indirect
|
||||
github.com/juju/ratelimit v1.0.2 // indirect
|
||||
github.com/klauspost/compress v1.18.0 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.10 // indirect
|
||||
github.com/onsi/ginkgo/v2 v2.23.4 // indirect
|
||||
github.com/pelletier/go-toml v1.9.5 // indirect
|
||||
github.com/pires/go-proxyproto v0.7.0 // indirect
|
||||
github.com/quic-go/quic-go v0.42.0 // indirect
|
||||
github.com/refraction-networking/utls v1.6.3 // indirect
|
||||
github.com/pires/go-proxyproto v0.8.1 // indirect
|
||||
github.com/quic-go/qpack v0.5.1 // indirect
|
||||
github.com/quic-go/quic-go v0.52.0 // indirect
|
||||
github.com/refraction-networking/utls v1.7.3 // indirect
|
||||
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 // indirect
|
||||
github.com/sagernet/sing v0.3.8 // indirect
|
||||
github.com/sagernet/sing-shadowsocks v0.2.6 // indirect
|
||||
github.com/seiflotfy/cuckoofilter v0.0.0-20220411075957-e3b120b3f5fb // indirect
|
||||
github.com/sagernet/sing v0.6.11 // indirect
|
||||
github.com/sagernet/sing-shadowsocks v0.2.8 // indirect
|
||||
github.com/seiflotfy/cuckoofilter v0.0.0-20240715131351-a2f2c23f1771 // indirect
|
||||
github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e // indirect
|
||||
github.com/vishvananda/netlink v1.2.1-beta.2.0.20230316163032-ced5aaba43e3 // indirect
|
||||
github.com/vishvananda/netns v0.0.4 // indirect
|
||||
github.com/xtls/reality v0.0.0-20231112171332-de1173cf2b19 // indirect
|
||||
go.uber.org/mock v0.4.0 // indirect
|
||||
github.com/vishvananda/netlink v1.3.1 // indirect
|
||||
github.com/vishvananda/netns v0.0.5 // indirect
|
||||
github.com/xtls/reality v0.0.0-20250608132114-50752aec6bfb // indirect
|
||||
go.uber.org/automaxprocs v1.6.0 // indirect
|
||||
go.uber.org/mock v0.5.2 // indirect
|
||||
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect
|
||||
golang.org/x/crypto v0.21.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 // indirect
|
||||
golang.org/x/mod v0.16.0 // indirect
|
||||
golang.org/x/net v0.22.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
golang.org/x/time v0.5.0 // indirect
|
||||
golang.org/x/tools v0.19.0 // indirect
|
||||
golang.org/x/crypto v0.39.0 // indirect
|
||||
golang.org/x/mod v0.25.0 // indirect
|
||||
golang.org/x/net v0.41.0 // indirect
|
||||
golang.org/x/sync v0.15.0 // indirect
|
||||
golang.org/x/sys v0.33.0 // indirect
|
||||
golang.org/x/text v0.26.0 // indirect
|
||||
golang.org/x/time v0.12.0 // indirect
|
||||
golang.org/x/tools v0.34.0 // indirect
|
||||
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
|
||||
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240308144416-29370a3891b7 // indirect
|
||||
google.golang.org/grpc v1.62.1 // indirect
|
||||
google.golang.org/protobuf v1.33.0 // indirect
|
||||
golang.zx2c4.com/wireguard v0.0.0-20250521234502-f333402bd9cb // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect
|
||||
google.golang.org/grpc v1.73.0 // indirect
|
||||
google.golang.org/protobuf v1.36.6 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gvisor.dev/gvisor v0.0.0-20231104011432-48a6d7d5bd0b // indirect
|
||||
lukechampine.com/blake3 v1.2.1 // indirect
|
||||
gvisor.dev/gvisor v0.0.0-20250606001031-fa4c4dd86b43 // indirect
|
||||
lukechampine.com/blake3 v1.4.1 // indirect
|
||||
)
|
||||
|
|
360
go.sum
360
go.sum
|
@ -1,268 +1,142 @@
|
|||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.37.0/go.mod h1:TS1dMSSfndXH133OKGwekG838Om/cQT0BUHV3HcBgoo=
|
||||
dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU=
|
||||
dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU=
|
||||
dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4=
|
||||
dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU=
|
||||
git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
|
||||
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
|
||||
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU=
|
||||
github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA=
|
||||
github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/OmarTariq612/goech v0.0.0-20240405204721-8e2e1dafd3a0 h1:Wo41lDOevRJSGpevP+8Pk5bANX7fJacO2w04aqLiC5I=
|
||||
github.com/OmarTariq612/goech v0.0.0-20240405204721-8e2e1dafd3a0/go.mod h1:FVGavL/QEBQDcBpr3fAojoK17xX5k9bicBphrOpP7uM=
|
||||
github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA=
|
||||
github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA=
|
||||
github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0=
|
||||
github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dgryski/go-metro v0.0.0-20200812162917-85c65e2d0165/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw=
|
||||
github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140 h1:y7y0Oa6UawqTFPCDw9JG6pdKt4F9pAhHv0B7FMGaGD0=
|
||||
github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
||||
github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk=
|
||||
github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/dgryski/go-metro v0.0.0-20250106013310-edb8663e5e33 h1:ucRHb6/lvW/+mTEIGbvhcYU3S8+uSNkuMjx/qZFfhtM=
|
||||
github.com/dgryski/go-metro v0.0.0-20250106013310-edb8663e5e33/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw=
|
||||
github.com/ghodss/yaml v1.0.1-0.20220118164431-d8423dcdf344 h1:Arcl6UOIS/kgO2nW3A65HN+7CMjSDP/gofXL4CZt1V4=
|
||||
github.com/ghodss/yaml v1.0.1-0.20220118164431-d8423dcdf344/go.mod h1:GIjDIg/heH5DOkXY3YJ/wNhfHsQHoXGjl8G8amsYQ1I=
|
||||
github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
|
||||
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
|
||||
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
|
||||
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
|
||||
github.com/golang/mock v1.7.0-rc.1 h1:YojYx61/OLFsiv6Rw1Z96LpldJIy31o+UHmwAUMJ6/U=
|
||||
github.com/golang/mock v1.7.0-rc.1/go.mod h1:s42URUywIqd+OcERslBJvOjepvNymP31m3q8d/GkuRs=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU=
|
||||
github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20240227163752-401108e1b7e7 h1:y3N7Bm7Y9/CtpiVkw/ZWj6lSlDF3F74SfKwfTCer72Q=
|
||||
github.com/google/pprof v0.0.0-20240227163752-401108e1b7e7/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik=
|
||||
github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
|
||||
github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
|
||||
github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
|
||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw=
|
||||
github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLAKQQg=
|
||||
github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||
github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
|
||||
github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||
github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
|
||||
github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/pprof v0.0.0-20250607225305-033d6d78b36a h1://KbezygeMJZCSHH+HgUZiTeSoiuFspbMg1ge+eFj18=
|
||||
github.com/google/pprof v0.0.0-20250607225305-033d6d78b36a/go.mod h1:5hDyRhoBCxViHszMt12TnOpEI4VVi+U8Gm9iphldiMA=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
|
||||
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/juju/ratelimit v1.0.2 h1:sRxmtRiajbvrcLQT7S+JbqU0ntsb9W2yhSdNN8tWfaI=
|
||||
github.com/juju/ratelimit v1.0.2/go.mod h1:qapgC/Gy+xNh9UxzV13HGGl/6UXNN+ct+vwSgWNm/qk=
|
||||
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
|
||||
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
|
||||
github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE=
|
||||
github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
|
||||
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
|
||||
github.com/miekg/dns v1.1.58 h1:ca2Hdkz+cDg/7eNF6V56jjzuZ4aCAE+DbVkILdQWG/4=
|
||||
github.com/miekg/dns v1.1.58/go.mod h1:Ypv+3b/KadlvW9vJfXOTf300O4UqaHFzFCuHz+rPkBY=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo=
|
||||
github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
|
||||
github.com/onsi/ginkgo/v2 v2.16.0 h1:7q1w9frJDzninhXxjZd+Y/x54XNjG/UlRLIYPZafsPM=
|
||||
github.com/onsi/ginkgo/v2 v2.16.0/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs=
|
||||
github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8=
|
||||
github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ=
|
||||
github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/miekg/dns v1.1.66 h1:FeZXOS3VCVsKnEAd+wBkjMC3D2K+ww66Cq3VnCINuJE=
|
||||
github.com/miekg/dns v1.1.66/go.mod h1:jGFzBsSNbJw6z1HYut1RKBKHA9PBdxeHrZG8J+gC2WE=
|
||||
github.com/onsi/ginkgo/v2 v2.23.4 h1:ktYTpKJAVZnDT4VjxSbiBenUjmlL/5QkBEocaWXiQus=
|
||||
github.com/onsi/ginkgo/v2 v2.23.4/go.mod h1:Bt66ApGPBFzHyR+JO10Zbt0Gsp4uWxu5mIOTusL46e8=
|
||||
github.com/onsi/gomega v1.36.3 h1:hID7cr8t3Wp26+cYnfcjR6HpJ00fdogN6dqZ1t6IylU=
|
||||
github.com/onsi/gomega v1.36.3/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0=
|
||||
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
|
||||
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
||||
github.com/pires/go-proxyproto v0.7.0 h1:IukmRewDQFWC7kfnb66CSomk2q/seBuilHBYFwyq0Hs=
|
||||
github.com/pires/go-proxyproto v0.7.0/go.mod h1:Vz/1JPY/OACxWGQNIRY2BeyDmpoaWmEP40O9LbuiFR4=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pires/go-proxyproto v0.8.1 h1:9KEixbdJfhrbtjpz/ZwCdWDD2Xem0NZ38qMYaASJgp0=
|
||||
github.com/pires/go-proxyproto v0.8.1/go.mod h1:ZKAAyp3cgy5Y5Mo4n9AlScrkCZwUy0g3Jf+slqQVcuU=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/quic-go/quic-go v0.42.0 h1:uSfdap0eveIl8KXnipv9K7nlwZ5IqLlYOpJ58u5utpM=
|
||||
github.com/quic-go/quic-go v0.42.0/go.mod h1:132kz4kL3F9vxhW3CtQJLDVwcFe5wdWeJXXijhsO57M=
|
||||
github.com/refraction-networking/utls v1.6.3 h1:MFOfRN35sSx6K5AZNIoESsBuBxS2LCgRilRIdHb6fDc=
|
||||
github.com/refraction-networking/utls v1.6.3/go.mod h1:yil9+7qSl+gBwJqztoQseO6Pr3h62pQoY1lXiNR/FPs=
|
||||
github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
|
||||
github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
|
||||
github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI=
|
||||
github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg=
|
||||
github.com/quic-go/quic-go v0.52.0 h1:/SlHrCRElyaU6MaEPKqKr9z83sBg2v4FLLvWM+Z47pA=
|
||||
github.com/quic-go/quic-go v0.52.0/go.mod h1:MFlGGpcpJqRAfmYi6NC2cptDPSxRWTOGNuP4wqrWmzQ=
|
||||
github.com/refraction-networking/utls v1.7.3 h1:L0WRhHY7Oq1T0zkdzVZMR6zWZv+sXbHB9zcuvsAEqCo=
|
||||
github.com/refraction-networking/utls v1.7.3/go.mod h1:TUhh27RHMGtQvjQq+RyO11P6ZNQNBb3N0v7wsEjKAIQ=
|
||||
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg=
|
||||
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3/go.mod h1:HgjTstvQsPGkxUsCd2KWxErBblirPizecHcpD3ffK+s=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/sagernet/sing v0.3.8 h1:gm4JKalPhydMYX2zFOTnnd4TXtM/16WFRqSjMepYQQk=
|
||||
github.com/sagernet/sing v0.3.8/go.mod h1:+60H3Cm91RnL9dpVGWDPHt0zTQImO9Vfqt9a4rSambI=
|
||||
github.com/sagernet/sing-shadowsocks v0.2.6 h1:xr7ylAS/q1cQYS8oxKKajhuQcchd5VJJ4K4UZrrpp0s=
|
||||
github.com/sagernet/sing-shadowsocks v0.2.6/go.mod h1:j2YZBIpWIuElPFL/5sJAj470bcn/3QQ5lxZUNKLDNAM=
|
||||
github.com/seiflotfy/cuckoofilter v0.0.0-20220411075957-e3b120b3f5fb h1:XfLJSPIOUX+osiMraVgIrMR27uMXnRJWGm1+GL8/63U=
|
||||
github.com/seiflotfy/cuckoofilter v0.0.0-20220411075957-e3b120b3f5fb/go.mod h1:bR6DqgcAl1zTcOX8/pE2Qkj9XO00eCNqmKb7lXP8EAg=
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY=
|
||||
github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM=
|
||||
github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0=
|
||||
github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
|
||||
github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ=
|
||||
github.com/shurcooL/gofontwoff v0.0.0-20180329035133-29b52fc0a18d/go.mod h1:05UtEgK5zq39gLST6uB0cf3NEHjETfB4Fgr3Gx5R9Vw=
|
||||
github.com/shurcooL/gopherjslib v0.0.0-20160914041154-feb6d3990c2c/go.mod h1:8d3azKNyqcHP1GaQE/c6dDgjkgSx2BZ4IoEi4F1reUI=
|
||||
github.com/shurcooL/highlight_diff v0.0.0-20170515013008-09bb4053de1b/go.mod h1:ZpfEhSmds4ytuByIcDnOLkTHGUI6KNqRNPDLHDk+mUU=
|
||||
github.com/shurcooL/highlight_go v0.0.0-20181028180052-98c3abbbae20/go.mod h1:UDKB5a1T23gOMUJrI+uSuH0VRDStOiUVSjBTRDVBVag=
|
||||
github.com/shurcooL/home v0.0.0-20181020052607-80b7ffcb30f9/go.mod h1:+rgNQw2P9ARFAs37qieuu7ohDNQ3gds9msbT2yn85sg=
|
||||
github.com/shurcooL/htmlg v0.0.0-20170918183704-d01228ac9e50/go.mod h1:zPn1wHpTIePGnXSHpsVPWEktKXHr6+SS6x/IKRb7cpw=
|
||||
github.com/shurcooL/httperror v0.0.0-20170206035902-86b7830d14cc/go.mod h1:aYMfkZ6DWSJPJ6c4Wwz3QtW22G7mf/PEgaB9k/ik5+Y=
|
||||
github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
|
||||
github.com/shurcooL/httpgzip v0.0.0-20180522190206-b1c53ac65af9/go.mod h1:919LwcH0M7/W4fcZ0/jy0qGght1GIhqyS/EgWGH2j5Q=
|
||||
github.com/shurcooL/issues v0.0.0-20181008053335-6292fdc1e191/go.mod h1:e2qWDig5bLteJ4fwvDAc2NHzqFEthkqn7aOZAOpj+PQ=
|
||||
github.com/shurcooL/issuesapp v0.0.0-20180602232740-048589ce2241/go.mod h1:NPpHK2TI7iSaM0buivtFUc9offApnI0Alt/K8hcHy0I=
|
||||
github.com/shurcooL/notifications v0.0.0-20181007000457-627ab5aea122/go.mod h1:b5uSkrEVM1jQUspwbixRBhaIjIzL2xazXp6kntxYle0=
|
||||
github.com/shurcooL/octicon v0.0.0-20181028054416-fa4f57f9efb2/go.mod h1:eWdoE5JD4R5UVWDucdOPg1g2fqQRq78IQa9zlOV1vpQ=
|
||||
github.com/shurcooL/reactions v0.0.0-20181006231557-f2e0b4ca5b82/go.mod h1:TCR1lToEk4d2s07G3XGfz2QrgHXg4RJBvjrOozvoWfk=
|
||||
github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4=
|
||||
github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw=
|
||||
github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE=
|
||||
github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA=
|
||||
github.com/sagernet/sing v0.6.11 h1:BXYwLYw2srH1Kdp1vlZgrK+1lAan5i2UdZ4lPWqEgUU=
|
||||
github.com/sagernet/sing v0.6.11/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
|
||||
github.com/sagernet/sing-shadowsocks v0.2.8 h1:PURj5PRoAkqeHh2ZW205RWzN9E9RtKCVCzByXruQWfE=
|
||||
github.com/sagernet/sing-shadowsocks v0.2.8/go.mod h1:lo7TWEMDcN5/h5B8S0ew+r78ZODn6SwVaFhvB6H+PTI=
|
||||
github.com/seiflotfy/cuckoofilter v0.0.0-20240715131351-a2f2c23f1771 h1:emzAzMZ1L9iaKCTxdy3Em8Wv4ChIAGnfiz18Cda70g4=
|
||||
github.com/seiflotfy/cuckoofilter v0.0.0-20240715131351-a2f2c23f1771/go.mod h1:bR6DqgcAl1zTcOX8/pE2Qkj9XO00eCNqmKb7lXP8EAg=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e h1:5QefA066A1tF8gHIiADmOVOV5LS43gt3ONnlEl3xkwI=
|
||||
github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e/go.mod h1:5t19P9LBIrNamL6AcMQOncg/r10y3Pc01AbHeMhwlpU=
|
||||
github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU=
|
||||
github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM=
|
||||
github.com/vishvananda/netlink v1.2.1-beta.2.0.20230316163032-ced5aaba43e3 h1:tkMT5pTye+1NlKIXETU78NXw0fyjnaNHmJyyLyzw8+U=
|
||||
github.com/vishvananda/netlink v1.2.1-beta.2.0.20230316163032-ced5aaba43e3/go.mod h1:cAAsePK2e15YDAMJNyOpGYEWNe4sIghTY7gpz4cX/Ik=
|
||||
github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
|
||||
github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8=
|
||||
github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
|
||||
github.com/xtls/reality v0.0.0-20231112171332-de1173cf2b19 h1:capMfFYRgH9BCLd6A3Er/cH3A9Nz3CU2KwxwOQZIePI=
|
||||
github.com/xtls/reality v0.0.0-20231112171332-de1173cf2b19/go.mod h1:dm4y/1QwzjGaK17ofi0Vs6NpKAHegZky8qk6J2JJZAE=
|
||||
github.com/xtls/xray-core v1.8.10 h1:qxae6gSteonpPI7EZyOyqw5HmRVRzmU07qs0l1GNqz4=
|
||||
github.com/xtls/xray-core v1.8.10/go.mod h1:Mc1t+kLBPE5a1EpsUNKjMLviGz3Y0XywxeEraJZAMlI=
|
||||
go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
|
||||
go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU=
|
||||
go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
|
||||
go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=
|
||||
github.com/vishvananda/netlink v1.3.1 h1:3AEMt62VKqz90r0tmNhog0r/PpWKmrEShJU0wJW6bV0=
|
||||
github.com/vishvananda/netlink v1.3.1/go.mod h1:ARtKouGSTGchR8aMwmkzC0qiNPrrWO5JS/XMVl45+b4=
|
||||
github.com/vishvananda/netns v0.0.5 h1:DfiHV+j8bA32MFM7bfEunvT8IAqQ/NzSJHtcmW5zdEY=
|
||||
github.com/vishvananda/netns v0.0.5/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
|
||||
github.com/xtls/reality v0.0.0-20250608132114-50752aec6bfb h1:X6ziJCMsFF8Ac/0F3W7+UbFdHZTu+r5nZ/smksHVxNQ=
|
||||
github.com/xtls/reality v0.0.0-20250608132114-50752aec6bfb/go.mod h1:yD47RN65bDLZgyHWMfFDiqlzrq4usDMt/Xzsk6tMbhw=
|
||||
github.com/xtls/xray-core v1.250516.1-0.20250608135303-fbae89d017ae h1:Be9MicJQI+Iup03zNG7QMEidpbJj3b4//IM8jIAnLKY=
|
||||
github.com/xtls/xray-core v1.250516.1-0.20250608135303-fbae89d017ae/go.mod h1:MkfIs2WZ5VLtZHAwDKosSS05Kx5zFFOzvly7Hy6pfPs=
|
||||
github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
|
||||
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
||||
go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ=
|
||||
go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y=
|
||||
go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M=
|
||||
go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE=
|
||||
go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY=
|
||||
go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w=
|
||||
go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs=
|
||||
go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc=
|
||||
go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
|
||||
go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
|
||||
go.uber.org/mock v0.5.2 h1:LbtPTcP8A5k9WPXj54PPPbjcI4Y6lhyOZXn+VS7wNko=
|
||||
go.uber.org/mock v0.5.2/go.mod h1:wLlUxC2vVTPTaE3UD51E0BGOAElKrILxhVSDYQLld5o=
|
||||
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBseWJUpBw5I82+2U4M=
|
||||
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y=
|
||||
golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw=
|
||||
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
|
||||
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 h1:LfspQV/FYTatPTr/3HzIcmiUFH7PGP+OQ6mgDYo3yuQ=
|
||||
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc=
|
||||
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/mobile v0.0.0-20231127183840-76ac6878050a h1:sYbmY3FwUWCBTodZL1S3JUuOvaW6kM2o+clDzzDNBWg=
|
||||
golang.org/x/mobile v0.0.0-20231127183840-76ac6878050a/go.mod h1:Ede7gF0KGoHlj822RtphAHK1jLdrcuRBZg0sF1Q+SPc=
|
||||
golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic=
|
||||
golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
|
||||
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
|
||||
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20220804214406-8e32c043e418/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
|
||||
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
|
||||
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw=
|
||||
golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc=
|
||||
golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM=
|
||||
golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U=
|
||||
golang.org/x/mobile v0.0.0-20250606033058-a2a15c67f36f h1:/n+PL2HlfqeSiDCuhdBbRNlGS/g2fM4OHufalHaTVG8=
|
||||
golang.org/x/mobile v0.0.0-20250606033058-a2a15c67f36f/go.mod h1:ESkJ836Z6LpG6mTVAhA48LpfW/8fNR0ifStlH2axyfg=
|
||||
golang.org/x/mod v0.25.0 h1:n7a+ZbQKQA/Ysbyb0/6IbB1H/X41mKgbhfv7AfG/44w=
|
||||
golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
|
||||
golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw=
|
||||
golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA=
|
||||
golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8=
|
||||
golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
|
||||
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M=
|
||||
golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=
|
||||
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
|
||||
golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
|
||||
golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo=
|
||||
golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg=
|
||||
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeunTOisW56dUokqW/FOteYJJ/yg=
|
||||
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI=
|
||||
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 h1:/jFs0duh4rdb8uIfPMv78iAJGcPKDeqAFnaLBropIC4=
|
||||
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173/go.mod h1:tkCQ4FQXmpAgYVh++1cq16/dH4QJtmvpRv19DWGAHSA=
|
||||
google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||
google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||
google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg=
|
||||
google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240308144416-29370a3891b7 h1:em/y72n4XlYRtayY/cVj6pnVzHa//BDA1BdoO+z9mdE=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240308144416-29370a3891b7/go.mod h1:UCOku4NytXMJuLQE5VuqA5lX3PcHCBo8pxNyvkf4xBs=
|
||||
google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||
google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=
|
||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.62.1 h1:B4n+nfKzOICUXMgyrNd19h/I9oH0L1pizfk1d4zSgTk=
|
||||
google.golang.org/grpc v1.62.1/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE=
|
||||
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
|
||||
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
golang.zx2c4.com/wireguard v0.0.0-20250521234502-f333402bd9cb h1:whnFRlWMcXI9d+ZbWg+4sHnLp52d5yiIPUxMBSt4X9A=
|
||||
golang.zx2c4.com/wireguard v0.0.0-20250521234502-f333402bd9cb/go.mod h1:rpwXGsirqLqN2L0JDJQlwOboGHmptD5ZD6T2VmcqhTw=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 h1:fc6jSaCT0vBduLYZHYrBBNY4dsWuvgyff9noRNDdBeE=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
|
||||
google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok=
|
||||
google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc=
|
||||
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
|
||||
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
|
@ -270,13 +144,7 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C
|
|||
gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o=
|
||||
gvisor.dev/gvisor v0.0.0-20231104011432-48a6d7d5bd0b h1:yqkg3pTifuKukuWanp8spDsL4irJkHF5WI0J47hU87o=
|
||||
gvisor.dev/gvisor v0.0.0-20231104011432-48a6d7d5bd0b/go.mod h1:10sU+Uh5KKNv1+2x2A0Gvzt8FjD3ASIhorV3YsauXhk=
|
||||
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI=
|
||||
lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k=
|
||||
sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck=
|
||||
sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0=
|
||||
gvisor.dev/gvisor v0.0.0-20250606001031-fa4c4dd86b43 h1:BEymU11L8DZSC4GNK48JYIR8EcHs+gFxtg9YfYlp68c=
|
||||
gvisor.dev/gvisor v0.0.0-20250606001031-fa4c4dd86b43/go.mod h1:3r5CMtNQMKIvBlrmM9xWUNamjKBYPOWyXOjmg5Kts3g=
|
||||
lukechampine.com/blake3 v1.4.1 h1:I3Smz7gso8w4/TunLKec6K2fn+kyKtDxr/xcQEN84Wg=
|
||||
lukechampine.com/blake3 v1.4.1/go.mod h1:QFosUxmjB8mnrWFSNwKmvxHpfY72bmD2tQ0kBMM3kwo=
|
||||
|
|
461
libv2ray_main.go
461
libv2ray_main.go
|
@ -14,186 +14,71 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
mobasset "golang.org/x/mobile/asset"
|
||||
|
||||
v2net "github.com/xtls/xray-core/common/net"
|
||||
v2filesystem "github.com/xtls/xray-core/common/platform/filesystem"
|
||||
v2core "github.com/xtls/xray-core/core"
|
||||
v2stats "github.com/xtls/xray-core/features/stats"
|
||||
v2serial "github.com/xtls/xray-core/infra/conf/serial"
|
||||
coreapplog "github.com/xtls/xray-core/app/log"
|
||||
corecommlog "github.com/xtls/xray-core/common/log"
|
||||
corenet "github.com/xtls/xray-core/common/net"
|
||||
corefilesystem "github.com/xtls/xray-core/common/platform/filesystem"
|
||||
"github.com/xtls/xray-core/common/serial"
|
||||
core "github.com/xtls/xray-core/core"
|
||||
corestats "github.com/xtls/xray-core/features/stats"
|
||||
coreserial "github.com/xtls/xray-core/infra/conf/serial"
|
||||
_ "github.com/xtls/xray-core/main/distro/all"
|
||||
v2internet "github.com/xtls/xray-core/transport/internet"
|
||||
|
||||
v2applog "github.com/xtls/xray-core/app/log"
|
||||
v2commlog "github.com/xtls/xray-core/common/log"
|
||||
mobasset "golang.org/x/mobile/asset"
|
||||
)
|
||||
|
||||
// Constants for environment variables
|
||||
const (
|
||||
v2Asset = "xray.location.asset"
|
||||
coreAsset = "xray.location.asset"
|
||||
coreCert = "xray.location.cert"
|
||||
xudpBaseKey = "xray.xudp.basekey"
|
||||
)
|
||||
|
||||
/*
|
||||
V2RayPoint V2Ray Point Server
|
||||
This is territory of Go, so no getter and setters!
|
||||
*/
|
||||
type V2RayPoint struct {
|
||||
SupportSet V2RayVPNServiceSupportsSet
|
||||
statsManager v2stats.Manager
|
||||
|
||||
dialer *ProtectedDialer
|
||||
v2rayOP sync.Mutex
|
||||
closeChan chan struct{}
|
||||
|
||||
Vpoint *v2core.Instance
|
||||
// CoreController represents a controller for managing Xray core instance lifecycle
|
||||
type CoreController struct {
|
||||
CallbackHandler CoreCallbackHandler
|
||||
statsManager corestats.Manager
|
||||
coreMutex sync.Mutex
|
||||
coreInstance *core.Instance
|
||||
IsRunning bool
|
||||
|
||||
DomainName string
|
||||
ConfigureFileContent string
|
||||
AsyncResolve bool
|
||||
}
|
||||
|
||||
/*V2RayVPNServiceSupportsSet To support Android VPN mode*/
|
||||
type V2RayVPNServiceSupportsSet interface {
|
||||
Setup(Conf string) int
|
||||
Prepare() int
|
||||
// CoreCallbackHandler defines interface for receiving callbacks and notifications from the core service
|
||||
type CoreCallbackHandler interface {
|
||||
Startup() int
|
||||
Shutdown() int
|
||||
Protect(int) bool
|
||||
OnEmitStatus(int, string) int
|
||||
}
|
||||
|
||||
/*RunLoop Run V2Ray main loop
|
||||
*/
|
||||
func (v *V2RayPoint) RunLoop(prefIPv6 bool) (err error) {
|
||||
v.v2rayOP.Lock()
|
||||
defer v.v2rayOP.Unlock()
|
||||
//Construct Context
|
||||
|
||||
if !v.IsRunning {
|
||||
v.closeChan = make(chan struct{})
|
||||
v.dialer.PrepareResolveChan()
|
||||
go func() {
|
||||
select {
|
||||
// wait until resolved
|
||||
case <-v.dialer.ResolveChan():
|
||||
// shutdown VPNService if server name can not reolved
|
||||
if !v.dialer.IsVServerReady() {
|
||||
log.Println("vServer cannot resolved, shutdown")
|
||||
v.StopLoop()
|
||||
v.SupportSet.Shutdown()
|
||||
// consoleLogWriter implements a log writer without datetime stamps
|
||||
// as Android system already adds timestamps to each log line
|
||||
type consoleLogWriter struct {
|
||||
logger *log.Logger // Standard logger
|
||||
}
|
||||
|
||||
// stop waiting if manually closed
|
||||
case <-v.closeChan:
|
||||
// setEnvVariable safely sets an environment variable and logs any errors encountered.
|
||||
func setEnvVariable(key, value string) {
|
||||
if err := os.Setenv(key, value); err != nil {
|
||||
log.Printf("Failed to set environment variable %s: %v. Please check your configuration.", key, err)
|
||||
}
|
||||
}()
|
||||
|
||||
if v.AsyncResolve {
|
||||
go func() {
|
||||
v.dialer.PrepareDomain(v.DomainName, v.closeChan, prefIPv6)
|
||||
close(v.dialer.ResolveChan())
|
||||
}()
|
||||
} else {
|
||||
v.dialer.PrepareDomain(v.DomainName, v.closeChan, prefIPv6)
|
||||
close(v.dialer.ResolveChan())
|
||||
}
|
||||
|
||||
err = v.pointloop()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
/*StopLoop Stop V2Ray main loop
|
||||
*/
|
||||
func (v *V2RayPoint) StopLoop() (err error) {
|
||||
v.v2rayOP.Lock()
|
||||
defer v.v2rayOP.Unlock()
|
||||
if v.IsRunning {
|
||||
close(v.closeChan)
|
||||
v.shutdownInit()
|
||||
v.SupportSet.OnEmitStatus(0, "Closed")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Delegate Funcation
|
||||
func (v V2RayPoint) QueryStats(tag string, direct string) int64 {
|
||||
if v.statsManager == nil {
|
||||
return 0
|
||||
}
|
||||
counter := v.statsManager.GetCounter(fmt.Sprintf("outbound>>>%s>>>traffic>>>%s", tag, direct))
|
||||
if counter == nil {
|
||||
return 0
|
||||
}
|
||||
return counter.Set(0)
|
||||
}
|
||||
|
||||
func (v *V2RayPoint) shutdownInit() {
|
||||
v.IsRunning = false
|
||||
v.Vpoint.Close()
|
||||
v.Vpoint = nil
|
||||
v.statsManager = nil
|
||||
}
|
||||
|
||||
func (v *V2RayPoint) pointloop() error {
|
||||
log.Println("loading core config")
|
||||
config, err := v2serial.LoadJSONConfig(strings.NewReader(v.ConfigureFileContent))
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return err
|
||||
}
|
||||
|
||||
log.Println("new core")
|
||||
v.Vpoint, err = v2core.New(config)
|
||||
if err != nil {
|
||||
v.Vpoint = nil
|
||||
log.Println(err)
|
||||
return err
|
||||
}
|
||||
v.statsManager = v.Vpoint.GetFeature(v2stats.ManagerType()).(v2stats.Manager)
|
||||
|
||||
log.Println("start core")
|
||||
v.IsRunning = true
|
||||
if err := v.Vpoint.Start(); err != nil {
|
||||
v.IsRunning = false
|
||||
log.Println(err)
|
||||
return err
|
||||
}
|
||||
|
||||
v.SupportSet.Prepare()
|
||||
v.SupportSet.Setup("")
|
||||
v.SupportSet.OnEmitStatus(0, "Running")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *V2RayPoint) MeasureDelay(url string) (int64, error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 12*time.Second)
|
||||
|
||||
go func() {
|
||||
select {
|
||||
case <-v.closeChan:
|
||||
// cancel request if close called during meansure
|
||||
cancel()
|
||||
case <-ctx.Done():
|
||||
}
|
||||
}()
|
||||
|
||||
return measureInstDelay(ctx, v.Vpoint, url)
|
||||
}
|
||||
|
||||
// InitV2Env set v2 asset path
|
||||
func InitV2Env(envPath string, key string) {
|
||||
//Initialize asset API, Since Raymond Will not let notify the asset location inside Process,
|
||||
//We need to set location outside V2Ray
|
||||
// InitCoreEnv initializes environment variables and file system handlers for the core
|
||||
// It sets up asset path, certificate path, XUDP base key and customizes the file reader
|
||||
// to support Android asset system
|
||||
func InitCoreEnv(envPath string, key string) {
|
||||
// Set asset/cert paths
|
||||
if len(envPath) > 0 {
|
||||
os.Setenv(v2Asset, envPath)
|
||||
}
|
||||
if len(key) > 0 {
|
||||
os.Setenv(xudpBaseKey, key)
|
||||
setEnvVariable(coreAsset, envPath)
|
||||
setEnvVariable(coreCert, envPath)
|
||||
}
|
||||
|
||||
//Now we handle read, fallback to gomobile asset (apk assets)
|
||||
v2filesystem.NewFileReader = func(path string) (io.ReadCloser, error) {
|
||||
// Set XUDP encryption key
|
||||
if len(key) > 0 {
|
||||
setEnvVariable(xudpBaseKey, key)
|
||||
}
|
||||
|
||||
// Custom file reader with path validation
|
||||
corefilesystem.NewFileReader = func(path string) (io.ReadCloser, error) {
|
||||
if _, err := os.Stat(path); os.IsNotExist(err) {
|
||||
_, file := filepath.Split(path)
|
||||
return mobasset.Open(file)
|
||||
|
@ -202,101 +87,242 @@ func InitV2Env(envPath string, key string) {
|
|||
}
|
||||
}
|
||||
|
||||
// NewCoreController initializes and returns a new CoreController instance
|
||||
// Sets up the console log handler and associates it with the provided callback handler
|
||||
func NewCoreController(s CoreCallbackHandler) *CoreController {
|
||||
// Register custom logger
|
||||
if err := coreapplog.RegisterHandlerCreator(
|
||||
coreapplog.LogType_Console,
|
||||
func(lt coreapplog.LogType, options coreapplog.HandlerCreatorOptions) (corecommlog.Handler, error) {
|
||||
return corecommlog.NewLogger(createStdoutLogWriter()), nil
|
||||
},
|
||||
); err != nil {
|
||||
log.Printf("Failed to register log handler: %v", err)
|
||||
}
|
||||
|
||||
return &CoreController{
|
||||
CallbackHandler: s,
|
||||
}
|
||||
}
|
||||
|
||||
// StartLoop initializes and starts the core processing loop
|
||||
// Thread-safe method that configures and runs the Xray core with the provided configuration
|
||||
// Returns immediately if the core is already running
|
||||
func (x *CoreController) StartLoop(configContent string) (err error) {
|
||||
x.coreMutex.Lock()
|
||||
defer x.coreMutex.Unlock()
|
||||
|
||||
if x.IsRunning {
|
||||
log.Println("Core is already running")
|
||||
return nil
|
||||
}
|
||||
|
||||
return x.doStartLoop(configContent)
|
||||
}
|
||||
|
||||
// StopLoop safely stops the core processing loop and releases resources
|
||||
// Thread-safe method that shuts down the core instance and triggers necessary callbacks
|
||||
func (x *CoreController) StopLoop() error {
|
||||
x.coreMutex.Lock()
|
||||
defer x.coreMutex.Unlock()
|
||||
|
||||
if x.IsRunning {
|
||||
x.doShutdown()
|
||||
x.CallbackHandler.OnEmitStatus(0, "Core stopped")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// QueryStats retrieves and resets traffic statistics for a specific outbound tag and direction
|
||||
// Returns the accumulated traffic value and resets the counter to zero
|
||||
// Returns 0 if the stats manager is not initialized or the counter doesn't exist
|
||||
func (x *CoreController) QueryStats(tag string, direct string) int64 {
|
||||
if x.statsManager == nil {
|
||||
return 0
|
||||
}
|
||||
counter := x.statsManager.GetCounter(fmt.Sprintf("outbound>>>%s>>>traffic>>>%s", tag, direct))
|
||||
if counter == nil {
|
||||
return 0
|
||||
}
|
||||
return counter.Set(0)
|
||||
}
|
||||
|
||||
// MeasureDelay measures network latency to a specified URL through the current core instance
|
||||
// Uses a 12-second timeout context and returns the round-trip time in milliseconds
|
||||
// An error is returned if the connection fails or returns an unexpected status
|
||||
func (x *CoreController) MeasureDelay(url string) (int64, error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 12*time.Second)
|
||||
defer cancel()
|
||||
|
||||
return measureInstDelay(ctx, x.coreInstance, url)
|
||||
}
|
||||
|
||||
// MeasureOutboundDelay measures the outbound delay for a given configuration and URL
|
||||
func MeasureOutboundDelay(ConfigureFileContent string, url string) (int64, error) {
|
||||
config, err := v2serial.LoadJSONConfig(strings.NewReader(ConfigureFileContent))
|
||||
config, err := coreserial.LoadJSONConfig(strings.NewReader(ConfigureFileContent))
|
||||
if err != nil {
|
||||
return -1, err
|
||||
return -1, fmt.Errorf("config load error: %w", err)
|
||||
}
|
||||
|
||||
// dont listen to anything for test purpose
|
||||
// Simplify config for testing
|
||||
config.Inbound = nil
|
||||
// config.App: (fakedns), log, dispatcher, InboundConfig, OutboundConfig, (stats), router, dns, (policy)
|
||||
// keep only basic features
|
||||
config.App = config.App[:5]
|
||||
var essentialApp []*serial.TypedMessage
|
||||
for _, app := range config.App {
|
||||
if app.Type == "xray.app.proxyman.OutboundConfig" ||
|
||||
app.Type == "xray.app.dispatcher.Config" ||
|
||||
app.Type == "xray.app.log.Config" {
|
||||
essentialApp = append(essentialApp, app)
|
||||
}
|
||||
}
|
||||
config.App = essentialApp
|
||||
|
||||
inst, err := v2core.New(config)
|
||||
inst, err := core.New(config)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
return -1, fmt.Errorf("instance creation failed: %w", err)
|
||||
}
|
||||
|
||||
inst.Start()
|
||||
delay, err := measureInstDelay(context.Background(), inst, url)
|
||||
inst.Close()
|
||||
return delay, err
|
||||
if err := inst.Start(); err != nil {
|
||||
return -1, fmt.Errorf("startup failed: %w", err)
|
||||
}
|
||||
defer inst.Close()
|
||||
return measureInstDelay(context.Background(), inst, url)
|
||||
}
|
||||
|
||||
/*NewV2RayPoint new V2RayPoint*/
|
||||
func NewV2RayPoint(s V2RayVPNServiceSupportsSet, adns bool) *V2RayPoint {
|
||||
// inject our own log writer
|
||||
v2applog.RegisterHandlerCreator(v2applog.LogType_Console,
|
||||
func(lt v2applog.LogType,
|
||||
options v2applog.HandlerCreatorOptions) (v2commlog.Handler, error) {
|
||||
return v2commlog.NewLogger(createStdoutLogWriter()), nil
|
||||
})
|
||||
|
||||
dialer := NewPreotectedDialer(s)
|
||||
v2internet.UseAlternativeSystemDialer(dialer)
|
||||
return &V2RayPoint{
|
||||
SupportSet: s,
|
||||
dialer: dialer,
|
||||
AsyncResolve: adns,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
CheckVersionX string
|
||||
This func will return libv2ray binding version and V2Ray version used.
|
||||
*/
|
||||
// CheckVersionX returns the library and Xray versions
|
||||
func CheckVersionX() string {
|
||||
var version = 27
|
||||
return fmt.Sprintf("Lib v%d, Xray-core v%s", version, v2core.Version())
|
||||
var version = 33
|
||||
return fmt.Sprintf("Lib v%d, Xray-core v%s", version, core.Version())
|
||||
}
|
||||
|
||||
func measureInstDelay(ctx context.Context, inst *v2core.Instance, url string) (int64, error) {
|
||||
// doShutdown shuts down the Xray instance and cleans up resources
|
||||
func (x *CoreController) doShutdown() {
|
||||
if x.coreInstance != nil {
|
||||
if err := x.coreInstance.Close(); err != nil {
|
||||
log.Printf("core shutdown error: %v", err)
|
||||
}
|
||||
x.coreInstance = nil
|
||||
}
|
||||
x.IsRunning = false
|
||||
x.statsManager = nil
|
||||
}
|
||||
|
||||
// doStartLoop sets up and starts the Xray core
|
||||
func (x *CoreController) doStartLoop(configContent string) error {
|
||||
log.Println("initializing core...")
|
||||
config, err := coreserial.LoadJSONConfig(strings.NewReader(configContent))
|
||||
if err != nil {
|
||||
return fmt.Errorf("config error: %w", err)
|
||||
}
|
||||
|
||||
x.coreInstance, err = core.New(config)
|
||||
if err != nil {
|
||||
return fmt.Errorf("core init failed: %w", err)
|
||||
}
|
||||
x.statsManager = x.coreInstance.GetFeature(corestats.ManagerType()).(corestats.Manager)
|
||||
|
||||
log.Println("starting core...")
|
||||
x.IsRunning = true
|
||||
if err := x.coreInstance.Start(); err != nil {
|
||||
x.IsRunning = false
|
||||
return fmt.Errorf("startup failed: %w", err)
|
||||
}
|
||||
|
||||
x.CallbackHandler.Startup()
|
||||
x.CallbackHandler.OnEmitStatus(0, "Started successfully, running")
|
||||
|
||||
log.Println("Starting core successfully")
|
||||
return nil
|
||||
}
|
||||
|
||||
// measureInstDelay measures the delay for an instance to a given URL
|
||||
func measureInstDelay(ctx context.Context, inst *core.Instance, url string) (int64, error) {
|
||||
if inst == nil {
|
||||
return -1, errors.New("core instance nil")
|
||||
return -1, errors.New("core instance is nil")
|
||||
}
|
||||
|
||||
tr := &http.Transport{
|
||||
TLSHandshakeTimeout: 6 * time.Second,
|
||||
DisableKeepAlives: true,
|
||||
DisableKeepAlives: false,
|
||||
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
|
||||
dest, err := v2net.ParseDestination(fmt.Sprintf("%s:%s", network, addr))
|
||||
dest, err := corenet.ParseDestination(fmt.Sprintf("%s:%s", network, addr))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return v2core.Dial(ctx, inst, dest)
|
||||
return core.Dial(ctx, inst, dest)
|
||||
},
|
||||
}
|
||||
|
||||
c := &http.Client{
|
||||
client := &http.Client{
|
||||
Transport: tr,
|
||||
Timeout: 12 * time.Second,
|
||||
}
|
||||
|
||||
if len(url) <= 0 {
|
||||
if url == "" {
|
||||
url = "https://www.google.com/generate_204"
|
||||
}
|
||||
req, _ := http.NewRequestWithContext(ctx, "GET", url, nil)
|
||||
start := time.Now()
|
||||
resp, err := c.Do(req)
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
return -1, fmt.Errorf("failed to create HTTP request: %w", err)
|
||||
}
|
||||
|
||||
var minDuration int64 = -1
|
||||
success := false
|
||||
var lastErr error
|
||||
|
||||
// Add exception handling and increase retry attempts
|
||||
const attempts = 2
|
||||
for i := 0; i < attempts; i++ {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
// Return immediately when context is canceled
|
||||
if !success {
|
||||
return -1, ctx.Err()
|
||||
}
|
||||
return minDuration, nil
|
||||
default:
|
||||
// Continue execution
|
||||
}
|
||||
|
||||
start := time.Now()
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
lastErr = err
|
||||
continue
|
||||
}
|
||||
|
||||
// Ensure response body is closed
|
||||
defer func(resp *http.Response) {
|
||||
if resp != nil && resp.Body != nil {
|
||||
resp.Body.Close()
|
||||
}
|
||||
}(resp)
|
||||
|
||||
if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusNoContent {
|
||||
return -1, fmt.Errorf("status != 20x: %s", resp.Status)
|
||||
}
|
||||
resp.Body.Close()
|
||||
return time.Since(start).Milliseconds(), nil
|
||||
lastErr = fmt.Errorf("invalid status: %s", resp.Status)
|
||||
continue
|
||||
}
|
||||
|
||||
// This struct creates our own log writer without datatime stamp
|
||||
// As Android adds time stamps on each line
|
||||
type consoleLogWriter struct {
|
||||
logger *log.Logger
|
||||
// Handle possible errors when reading response body
|
||||
if _, err := io.Copy(io.Discard, resp.Body); err != nil {
|
||||
lastErr = fmt.Errorf("failed to read response body: %w", err)
|
||||
continue
|
||||
}
|
||||
|
||||
duration := time.Since(start).Milliseconds()
|
||||
if !success || duration < minDuration {
|
||||
minDuration = duration
|
||||
}
|
||||
|
||||
success = true
|
||||
}
|
||||
if !success {
|
||||
return -1, lastErr
|
||||
}
|
||||
return minDuration, nil
|
||||
}
|
||||
|
||||
// Log writer implementation
|
||||
func (w *consoleLogWriter) Write(s string) error {
|
||||
w.logger.Print(s)
|
||||
return nil
|
||||
|
@ -306,10 +332,11 @@ func (w *consoleLogWriter) Close() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// This logger won't print data/time stamps
|
||||
func createStdoutLogWriter() v2commlog.WriterCreator {
|
||||
return func() v2commlog.Writer {
|
||||
// createStdoutLogWriter creates a logger that won't print date/time stamps
|
||||
func createStdoutLogWriter() corecommlog.WriterCreator {
|
||||
return func() corecommlog.Writer {
|
||||
return &consoleLogWriter{
|
||||
logger: log.New(os.Stdout, "", 0)}
|
||||
logger: log.New(os.Stdout, "", 0),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,318 +0,0 @@
|
|||
package libv2ray
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
v2net "github.com/xtls/xray-core/common/net"
|
||||
"github.com/xtls/xray-core/features/dns"
|
||||
"github.com/xtls/xray-core/features/outbound"
|
||||
v2internet "github.com/xtls/xray-core/transport/internet"
|
||||
)
|
||||
|
||||
type protectSet interface {
|
||||
Protect(int) bool
|
||||
}
|
||||
|
||||
type resolved struct {
|
||||
domain string
|
||||
IPs []net.IP
|
||||
Port int
|
||||
lastResolved time.Time
|
||||
ipIdx uint8
|
||||
ipLock sync.Mutex
|
||||
lastSwitched time.Time
|
||||
}
|
||||
|
||||
// NextIP switch to another resolved result.
|
||||
// there still be race-condition here if multiple err concurently occured
|
||||
// may cause idx keep switching,
|
||||
// but that's an outside error can hardly handled here
|
||||
func (r *resolved) NextIP() {
|
||||
r.ipLock.Lock()
|
||||
defer r.ipLock.Unlock()
|
||||
|
||||
if len(r.IPs) > 1 {
|
||||
|
||||
// throttle, don't switch too quickly
|
||||
now := time.Now()
|
||||
if now.Sub(r.lastSwitched) < time.Second*5 {
|
||||
log.Println("switch too quickly")
|
||||
return
|
||||
}
|
||||
r.lastSwitched = now
|
||||
r.ipIdx++
|
||||
|
||||
} else {
|
||||
return
|
||||
}
|
||||
|
||||
if r.ipIdx >= uint8(len(r.IPs)) {
|
||||
r.ipIdx = 0
|
||||
}
|
||||
|
||||
log.Printf("switched to next IP: %v", r.IPs[r.ipIdx])
|
||||
}
|
||||
|
||||
func (r *resolved) currentIP() net.IP {
|
||||
r.ipLock.Lock()
|
||||
defer r.ipLock.Unlock()
|
||||
if len(r.IPs) > 0 {
|
||||
return r.IPs[r.ipIdx]
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewPreotectedDialer ...
|
||||
func NewPreotectedDialer(p protectSet) *ProtectedDialer {
|
||||
d := &ProtectedDialer{
|
||||
// prefer native lookup on Android
|
||||
resolver: &net.Resolver{PreferGo: false},
|
||||
protectSet: p,
|
||||
}
|
||||
return d
|
||||
}
|
||||
|
||||
// ProtectedDialer ...
|
||||
type ProtectedDialer struct {
|
||||
currentServer string
|
||||
resolveChan chan struct{}
|
||||
preferIPv6 bool
|
||||
|
||||
vServer *resolved
|
||||
resolver *net.Resolver
|
||||
|
||||
protectSet
|
||||
}
|
||||
|
||||
func (d *ProtectedDialer) IsVServerReady() bool {
|
||||
return (d.vServer != nil)
|
||||
}
|
||||
|
||||
func (d *ProtectedDialer) PrepareResolveChan() {
|
||||
d.resolveChan = make(chan struct{})
|
||||
}
|
||||
|
||||
func (d *ProtectedDialer) ResolveChan() chan struct{} {
|
||||
return d.resolveChan
|
||||
}
|
||||
|
||||
// simplicated version of golang: internetAddrList in src/net/ipsock.go
|
||||
func (d *ProtectedDialer) lookupAddr(addr string) (*resolved, error) {
|
||||
|
||||
var (
|
||||
err error
|
||||
host, port string
|
||||
portnum int
|
||||
)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
|
||||
if host, port, err = net.SplitHostPort(addr); err != nil {
|
||||
log.Printf("PrepareDomain SplitHostPort Err: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if portnum, err = d.resolver.LookupPort(ctx, "tcp", port); err != nil {
|
||||
log.Printf("PrepareDomain LookupPort Err: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
addrs, err := d.resolver.LookupIPAddr(ctx, host)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(addrs) == 0 {
|
||||
return nil, fmt.Errorf("domain %s Failed to resolve", addr)
|
||||
}
|
||||
|
||||
IPs := make([]net.IP, 0)
|
||||
//ipv6 is prefer, append ipv6 then ipv4
|
||||
//ipv6 is not prefer, append ipv4 then ipv6
|
||||
if(d.preferIPv6) {
|
||||
for _, ia := range addrs {
|
||||
if(ia.IP.To4() == nil) {
|
||||
IPs = append(IPs, ia.IP)
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, ia := range addrs {
|
||||
if(ia.IP.To4() != nil) {
|
||||
IPs = append(IPs, ia.IP)
|
||||
}
|
||||
}
|
||||
if(!d.preferIPv6) {
|
||||
for _, ia := range addrs {
|
||||
if(ia.IP.To4() == nil) {
|
||||
IPs = append(IPs, ia.IP)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rs := &resolved{
|
||||
domain: host,
|
||||
IPs: IPs,
|
||||
Port: portnum,
|
||||
lastResolved: time.Now(),
|
||||
}
|
||||
|
||||
return rs, nil
|
||||
}
|
||||
|
||||
// PrepareDomain caches direct v2ray server host
|
||||
func (d *ProtectedDialer) PrepareDomain(domainName string, closeCh <-chan struct{}, prefIPv6 bool) {
|
||||
log.Printf("Preparing Domain: %s", domainName)
|
||||
d.currentServer = domainName
|
||||
d.preferIPv6 = prefIPv6
|
||||
|
||||
maxRetry := 10
|
||||
for {
|
||||
if maxRetry == 0 {
|
||||
log.Println("PrepareDomain maxRetry reached. exiting.")
|
||||
return
|
||||
}
|
||||
|
||||
resolved, err := d.lookupAddr(domainName)
|
||||
if err != nil {
|
||||
maxRetry--
|
||||
log.Printf("PrepareDomain err: %v\n", err)
|
||||
select {
|
||||
case <-closeCh:
|
||||
log.Printf("PrepareDomain exit due to core closed")
|
||||
return
|
||||
case <-time.After(time.Second * 2):
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
d.vServer = resolved
|
||||
log.Printf("Prepare Result:\n Domain: %s\n Port: %d\n IPs: %v\n",
|
||||
resolved.domain, resolved.Port, resolved.IPs)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (d *ProtectedDialer) getFd(network v2net.Network) (fd int, err error) {
|
||||
switch network {
|
||||
case v2net.Network_TCP:
|
||||
fd, err = unix.Socket(unix.AF_INET6, unix.SOCK_STREAM, unix.IPPROTO_TCP)
|
||||
case v2net.Network_UDP:
|
||||
fd, err = unix.Socket(unix.AF_INET6, unix.SOCK_DGRAM, unix.IPPROTO_UDP)
|
||||
default:
|
||||
err = fmt.Errorf("unknow network")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Init implement internet.SystemDialer
|
||||
func (d *ProtectedDialer) Init(_ dns.Client, _ outbound.Manager) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
// Dial exported as the protected dial method
|
||||
func (d *ProtectedDialer) Dial(ctx context.Context,
|
||||
src v2net.Address, dest v2net.Destination, sockopt *v2internet.SocketConfig) (net.Conn, error) {
|
||||
|
||||
network := dest.Network.SystemString()
|
||||
Address := dest.NetAddr()
|
||||
|
||||
// v2ray server address,
|
||||
// try to connect fixed IP if multiple IP parsed from domain,
|
||||
// and switch to next IP if error occurred
|
||||
if Address == d.currentServer {
|
||||
if d.vServer == nil {
|
||||
log.Println("Dial pending prepare ...", Address)
|
||||
<-d.resolveChan
|
||||
|
||||
// user may close connection during PrepareDomain,
|
||||
// fast return release resources.
|
||||
if d.vServer == nil {
|
||||
return nil, fmt.Errorf("fail to prepare domain %s", d.currentServer)
|
||||
}
|
||||
}
|
||||
|
||||
// if time.Since(d.vServer.lastResolved) > time.Minute*30 {
|
||||
// go d.PrepareDomain(Address, nil, d.preferIPv6)
|
||||
// }
|
||||
|
||||
fd, err := d.getFd(dest.Network)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
curIP := d.vServer.currentIP()
|
||||
conn, err := d.fdConn(ctx, curIP, d.vServer.Port, fd)
|
||||
if err != nil {
|
||||
d.vServer.NextIP()
|
||||
return nil, err
|
||||
}
|
||||
log.Printf("Using Prepared: %s", curIP)
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
// v2ray connecting to "domestic" servers, no caching results
|
||||
log.Printf("Not Using Prepared: %s,%s", network, Address)
|
||||
resolved, err := d.lookupAddr(Address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fd, err := d.getFd(dest.Network)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// use the first resolved address.
|
||||
// the result IP may vary, eg: IPv6 addrs comes first if client has ipv6 address
|
||||
return d.fdConn(ctx, resolved.IPs[0], resolved.Port, fd)
|
||||
}
|
||||
|
||||
func (d *ProtectedDialer) DestIpAddress() net.IP {
|
||||
return d.vServer.currentIP()
|
||||
}
|
||||
|
||||
func (d *ProtectedDialer) fdConn(ctx context.Context, ip net.IP, port int, fd int) (net.Conn, error) {
|
||||
|
||||
defer unix.Close(fd)
|
||||
|
||||
// call android VPN service to "protect" the fd connecting straight out
|
||||
if !d.Protect(fd) {
|
||||
log.Printf("fdConn fail to protect, Close Fd: %d", fd)
|
||||
return nil, errors.New("fail to protect")
|
||||
}
|
||||
|
||||
sa := &unix.SockaddrInet6{
|
||||
Port: port,
|
||||
}
|
||||
copy(sa.Addr[:], ip.To16())
|
||||
|
||||
if err := unix.Connect(fd, sa); err != nil {
|
||||
log.Printf("fdConn unix.Connect err, Close Fd: %d Err: %v", fd, err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
file := os.NewFile(uintptr(fd), "Socket")
|
||||
if file == nil {
|
||||
// returned value will be nil if fd is not a valid file descriptor
|
||||
return nil, errors.New("fdConn fd invalid")
|
||||
}
|
||||
|
||||
defer file.Close()
|
||||
//Closing conn does not affect file, and closing file does not affect conn.
|
||||
conn, err := net.FileConn(file)
|
||||
if err != nil {
|
||||
log.Printf("fdConn FileConn Close Fd: %d Err: %v", fd, err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return conn, nil
|
||||
}
|
|
@ -1,151 +0,0 @@
|
|||
package libv2ray
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
v2net "github.com/xtls/xray-core/common/net"
|
||||
)
|
||||
|
||||
type fakeSupportSet struct{}
|
||||
|
||||
func (f fakeSupportSet) Protect(int) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func TestProtectedDialer_PrepareDomain(t *testing.T) {
|
||||
type args struct {
|
||||
domainName string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
}{
|
||||
// TODO: Add test cases.
|
||||
{"", args{"baidu.com:80"}},
|
||||
// {"", args{"cloudflare.com:443"}},
|
||||
// {"", args{"apple.com:443"}},
|
||||
// {"", args{"110.110.110.110:443"}},
|
||||
// {"", args{"[2002:1234::1]:443"}},
|
||||
}
|
||||
d := NewPreotectedDialer(fakeSupportSet{})
|
||||
for _, tt := range tests {
|
||||
ch := make(chan struct{})
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
go d.PrepareDomain(tt.args.domainName, ch, false)
|
||||
|
||||
time.Sleep(time.Second)
|
||||
go d.vServer.NextIP()
|
||||
t.Log(d.vServer.currentIP())
|
||||
})
|
||||
}
|
||||
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
|
||||
func TestProtectedDialer_Dial(t *testing.T) {
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
wantErr bool
|
||||
}{
|
||||
// TODO: Add test cases.
|
||||
{"baidu.com:80", false},
|
||||
{"cloudflare.com:80", false},
|
||||
{"172.16.192.11:80", true},
|
||||
// {"172.16.192.10:80", true},
|
||||
// {"[2fff:4322::1]:443", true},
|
||||
// {"[fc00::1]:443", true},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
ch := make(chan struct{})
|
||||
|
||||
d := NewPreotectedDialer(fakeSupportSet{})
|
||||
d.currentServer = tt.name
|
||||
|
||||
go d.PrepareDomain(tt.name, ch, false)
|
||||
|
||||
var wg sync.WaitGroup
|
||||
|
||||
dial := func() {
|
||||
defer wg.Done()
|
||||
dest, _ := v2net.ParseDestination("tcp:" + tt.name)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
||||
defer cancel()
|
||||
|
||||
conn, err := d.Dial(ctx, nil, dest, nil)
|
||||
if err != nil {
|
||||
t.Log(err)
|
||||
return
|
||||
}
|
||||
_host, _, _ := net.SplitHostPort(tt.name)
|
||||
fmt.Fprintf(conn, fmt.Sprintf("GET / HTTP/1.1\r\nHost: %s\r\n\r\n", _host))
|
||||
status, err := bufio.NewReader(conn).ReadString('\n')
|
||||
t.Logf("%#v, %#v\n", status, err)
|
||||
conn.Close()
|
||||
}
|
||||
|
||||
for n := 0; n < 3; n++ {
|
||||
wg.Add(1)
|
||||
go dial()
|
||||
// time.Sleep(time.Millisecond * 10)
|
||||
// d.pendingMap[tt.name] = make(chan struct{})
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_resolved_NextIP(t *testing.T) {
|
||||
type fields struct {
|
||||
domain string
|
||||
IPs []net.IP
|
||||
Port int
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
}{
|
||||
// TODO: Add test cases.
|
||||
{"test1",
|
||||
fields{
|
||||
domain: "www.baidu.com",
|
||||
IPs: []net.IP{
|
||||
net.ParseIP("1.2.3.4"),
|
||||
net.ParseIP("4.3.2.1"),
|
||||
net.ParseIP("1234::1"),
|
||||
net.ParseIP("4321::1"),
|
||||
},
|
||||
}},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
r := &resolved{
|
||||
domain: tt.fields.domain,
|
||||
IPs: tt.fields.IPs,
|
||||
Port: tt.fields.Port,
|
||||
}
|
||||
t.Logf("%v", r.IPs)
|
||||
t.Logf("%v", r.currentIP())
|
||||
r.NextIP()
|
||||
t.Logf("%v", r.currentIP())
|
||||
r.NextIP()
|
||||
t.Logf("%v", r.currentIP())
|
||||
r.NextIP()
|
||||
t.Logf("%v", r.currentIP())
|
||||
time.Sleep(3 * time.Second)
|
||||
r.NextIP()
|
||||
t.Logf("%v", r.currentIP())
|
||||
time.Sleep(5 * time.Second)
|
||||
r.NextIP()
|
||||
t.Logf("%v", r.currentIP())
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue