diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index aab209f8..59213b95 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: submodules: true diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2ba27852..5c39d1b4 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -7,6 +7,8 @@ on: push: branches: - main + tags: + - "*.*.*" paths: - '.github/workflows/release.yml' - '**.js' @@ -35,10 +37,10 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Setup Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: go-version-file: go.mod check-latest: true @@ -84,7 +86,7 @@ jobs: cd x-ui/bin # Download dependencies - Xray_URL="https://github.com/XTLS/Xray-core/releases/download/v25.8.3/" + Xray_URL="https://github.com/XTLS/Xray-core/releases/download/v25.9.11/" if [ "${{ matrix.platform }}" == "amd64" ]; then wget -q ${Xray_URL}Xray-linux-64.zip unzip Xray-linux-64.zip @@ -133,10 +135,87 @@ jobs: - name: Upload files to GH release uses: svenstaro/upload-release-action@v2 - if: github.event_name == 'release' && github.event.action == 'published' + if: | + (github.event_name == 'release' && github.event.action == 'published') || + (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')) with: repo_token: ${{ secrets.GITHUB_TOKEN }} tag: ${{ github.ref }} file: x-ui-linux-${{ matrix.platform }}.tar.gz asset_name: x-ui-linux-${{ matrix.platform }}.tar.gz + overwrite: true prerelease: true + + # ================================= + # Windows Build + # ================================= + build-windows: + name: Build for Windows + permissions: + contents: write + strategy: + matrix: + platform: + - amd64 + runs-on: windows-latest + steps: + - name: Checkout repository + uses: actions/checkout@v5 + + - name: Setup Go + uses: actions/setup-go@v6 + with: + go-version-file: go.mod + check-latest: true + + - name: Build X-UI for Windows + shell: pwsh + run: | + $env:CGO_ENABLED="1" + $env:GOOS="windows" + $env:GOARCH="amd64" + go build -ldflags "-w -s" -o xui-release.exe -v main.go + + mkdir x-ui + Copy-Item xui-release.exe x-ui\ + mkdir x-ui\bin + cd x-ui\bin + + # Download Xray for Windows + $Xray_URL = "https://github.com/XTLS/Xray-core/releases/download/v25.9.11/" + Invoke-WebRequest -Uri "${Xray_URL}Xray-windows-64.zip" -OutFile "Xray-windows-64.zip" + Expand-Archive -Path "Xray-windows-64.zip" -DestinationPath . + Remove-Item "Xray-windows-64.zip" + Remove-Item geoip.dat, geosite.dat -ErrorAction SilentlyContinue + Invoke-WebRequest -Uri "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat" -OutFile "geoip.dat" + Invoke-WebRequest -Uri "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat" -OutFile "geosite.dat" + Invoke-WebRequest -Uri "https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geoip.dat" -OutFile "geoip_IR.dat" + Invoke-WebRequest -Uri "https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geosite.dat" -OutFile "geosite_IR.dat" + Rename-Item xray.exe xray-windows-amd64.exe + cd .. + Copy-Item -Path ..\windows_files\* -Destination . -Recurse + cd .. + + - name: Package to Zip + shell: pwsh + run: | + Compress-Archive -Path .\x-ui -DestinationPath "x-ui-windows-amd64.zip" + + - name: Upload files to Artifacts + uses: actions/upload-artifact@v4 + with: + name: x-ui-windows-amd64 + path: ./x-ui-windows-amd64.zip + + - name: Upload files to GH release + uses: svenstaro/upload-release-action@v2 + if: | + (github.event_name == 'release' && github.event.action == 'published') || + (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')) + with: + repo_token: ${{ secrets.GITHUB_TOKEN }} + tag: ${{ github.ref }} + file: x-ui-windows-amd64.zip + asset_name: x-ui-windows-amd64.zip + overwrite: true + prerelease: true \ No newline at end of file diff --git a/DockerInitFiles.sh b/DockerInitFiles.sh index bc7b0f6d..0d5b79d5 100755 --- a/DockerInitFiles.sh +++ b/DockerInitFiles.sh @@ -23,7 +23,7 @@ case $1 in esac mkdir -p build/bin cd build/bin -wget -q "https://github.com/XTLS/Xray-core/releases/download/v25.8.3/Xray-linux-${ARCH}.zip" +wget -q "https://github.com/XTLS/Xray-core/releases/download/v25.9.11/Xray-linux-${ARCH}.zip" unzip "Xray-linux-${ARCH}.zip" rm -f "Xray-linux-${ARCH}.zip" geoip.dat geosite.dat LICENSE README.md mv xray "xray-linux-${FNAME}" diff --git a/database/model/model.go b/database/model/model.go index c999462b..f8e1fe23 100644 --- a/database/model/model.go +++ b/database/model/model.go @@ -79,3 +79,10 @@ type Client struct { SubID string `json:"subId" form:"subId"` Reset int `json:"reset" form:"reset"` } + +type VLESSSettings struct { + Clients []Client `json:"clients"` + Decryption string `json:"decryption"` + Encryption string `json:"encryption"` + Fallbacks []any `json:"fallbacks"` +} diff --git a/go.mod b/go.mod index 0be1e1cf..7aa83030 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module x-ui -go 1.24.5 +go 1.25.1 require ( github.com/gin-contrib/gzip v1.2.3 @@ -12,30 +12,31 @@ require ( github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 github.com/pelletier/go-toml/v2 v2.2.4 github.com/robfig/cron/v3 v3.0.1 - github.com/shirou/gopsutil/v4 v4.25.7 - github.com/xtls/xray-core v1.250803.0 + github.com/shirou/gopsutil/v4 v4.25.8 + github.com/xtls/xray-core v1.250911.0 go.uber.org/atomic v1.11.0 - golang.org/x/text v0.27.0 - google.golang.org/grpc v1.74.2 + golang.org/x/text v0.29.0 + google.golang.org/grpc v1.75.1 gorm.io/driver/sqlite v1.6.0 - gorm.io/gorm v1.30.1 + gorm.io/gorm v1.31.0 ) require ( - github.com/andybalholm/brotli v1.0.6 // indirect - github.com/bytedance/sonic v1.14.0 // indirect + github.com/andybalholm/brotli v1.2.0 // indirect + github.com/bytedance/gopkg v0.1.3 // indirect + github.com/bytedance/sonic v1.14.1 // indirect github.com/bytedance/sonic/loader v0.3.0 // indirect github.com/cloudflare/circl v1.6.1 // indirect github.com/cloudwego/base64x v0.1.6 // indirect - github.com/dgryski/go-metro v0.0.0-20200812162917-85c65e2d0165 // indirect + github.com/dgryski/go-metro v0.0.0-20250106013310-edb8663e5e33 // indirect github.com/ebitengine/purego v0.8.4 // indirect - github.com/gabriel-vasile/mimetype v1.4.8 // indirect + github.com/gabriel-vasile/mimetype v1.4.10 // indirect github.com/gin-contrib/sse v1.1.0 // indirect github.com/go-ole/go-ole v1.3.0 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.27.0 // indirect - github.com/google/btree v1.1.2 // indirect + github.com/google/btree v1.1.3 // indirect github.com/gorilla/context v1.1.2 // indirect github.com/gorilla/securecookie v1.1.2 // indirect github.com/gorilla/sessions v1.4.0 // indirect @@ -45,13 +46,13 @@ require ( github.com/json-iterator/go v1.1.12 // 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/klauspost/cpuid/v2 v2.3.0 // indirect github.com/kr/text v0.2.0 // indirect github.com/leodido/go-urn v1.4.0 // indirect - github.com/lufia/plan9stats v0.0.0-20250317134145-8bc96cf8fc35 // indirect + github.com/lufia/plan9stats v0.0.0-20250827001030-24949be3fa54 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-sqlite3 v1.14.30 // indirect - github.com/miekg/dns v1.1.67 // indirect + github.com/mattn/go-sqlite3 v1.14.32 // indirect + github.com/miekg/dns v1.1.68 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pires/go-proxyproto v0.8.1 // indirect @@ -61,33 +62,33 @@ require ( github.com/refraction-networking/utls v1.8.0 // indirect github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 // indirect github.com/rogpeppe/go-internal v1.14.1 // indirect - github.com/sagernet/sing v0.5.1 // indirect - github.com/sagernet/sing-shadowsocks v0.2.7 // indirect + github.com/sagernet/sing v0.7.10 // indirect + github.com/sagernet/sing-shadowsocks v0.2.9 // indirect github.com/seiflotfy/cuckoofilter v0.0.0-20240715131351-a2f2c23f1771 // indirect github.com/tklauser/go-sysconf v0.3.15 // indirect github.com/tklauser/numcpus v0.10.0 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect - github.com/ugorji/go/codec v1.2.12 // indirect + github.com/ugorji/go/codec v1.3.0 // indirect github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e // indirect github.com/vishvananda/netlink v1.3.1 // indirect github.com/vishvananda/netns v0.0.5 // indirect - github.com/xtls/reality v0.0.0-20250725142056-5b52a03d4fb7 // indirect + github.com/xtls/reality v0.0.0-20250904214705-431b6ff8c67c // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect - go.uber.org/mock v0.5.0 // indirect + go.uber.org/mock v0.6.0 // indirect go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect - golang.org/x/arch v0.19.0 // indirect - golang.org/x/crypto v0.40.0 // indirect - golang.org/x/mod v0.25.0 // indirect - golang.org/x/net v0.42.0 // indirect - golang.org/x/sync v0.16.0 // indirect - golang.org/x/sys v0.34.0 // indirect - golang.org/x/time v0.7.0 // indirect - golang.org/x/tools v0.34.0 // indirect + golang.org/x/arch v0.21.0 // indirect + golang.org/x/crypto v0.42.0 // indirect + golang.org/x/mod v0.28.0 // indirect + golang.org/x/net v0.44.0 // indirect + golang.org/x/sync v0.17.0 // indirect + golang.org/x/sys v0.36.0 // indirect + golang.org/x/time v0.13.0 // indirect + golang.org/x/tools v0.37.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-20250528174236-200df99c418a // indirect - google.golang.org/protobuf v1.36.6 // indirect + golang.zx2c4.com/wireguard v0.0.0-20250521234502-f333402bd9cb // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250908214217-97024824d090 // indirect + google.golang.org/protobuf v1.36.9 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - gvisor.dev/gvisor v0.0.0-20250428193742-2d800c3129d5 // indirect + gvisor.dev/gvisor v0.0.0-20250503011706-39ed1f5ac29c // indirect lukechampine.com/blake3 v1.4.1 // indirect ) diff --git a/go.sum b/go.sum index 0b1d4581..ac56ea4e 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,11 @@ github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg= github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= -github.com/andybalholm/brotli v1.0.6 h1:Yf9fFpf49Zrxb9NlQaluyE92/+X7UVHlhMNJN2sxfOI= -github.com/andybalholm/brotli v1.0.6/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= -github.com/bytedance/sonic v1.14.0 h1:/OfKt8HFw0kh2rj8N0F6C/qPGRESq0BbaNZgcNXXzQQ= -github.com/bytedance/sonic v1.14.0/go.mod h1:WoEbx8WTcFJfzCe0hbmyTGrfjt8PzNEBdxlNUO24NhA= +github.com/andybalholm/brotli v1.2.0 h1:ukwgCxwYrmACq68yiUqwIWnGY0cTPox/M94sVwToPjQ= +github.com/andybalholm/brotli v1.2.0/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY= +github.com/bytedance/gopkg v0.1.3 h1:TPBSwH8RsouGCBcMBktLt1AymVo2TVsBVCY4b6TnZ/M= +github.com/bytedance/gopkg v0.1.3/go.mod h1:576VvJ+eJgyCzdjS+c4+77QF3p7ubbtiKARP3TxducM= +github.com/bytedance/sonic v1.14.1 h1:FBMC0zVz5XUmE4z9wF4Jey0An5FueFvOsTKKKtwIl7w= +github.com/bytedance/sonic v1.14.1/go.mod h1:gi6uhQLMbTdeP0muCnrjHLeCUPyb70ujhnNlhOylAFc= github.com/bytedance/sonic/loader v0.3.0 h1:dskwH8edlzNMctoruo8FPTJDF3vLtDT0sXZwvZJyqeA= github.com/bytedance/sonic/loader v0.3.0/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0= @@ -14,12 +16,13 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3 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 h1:BS21ZUJ/B5X2UVUbczfmdWH7GapPWAhxcMsDnjJTU1E= github.com/dgryski/go-metro v0.0.0-20200812162917-85c65e2d0165/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw= +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/ebitengine/purego v0.8.4 h1:CF7LEKg5FFOsASUj0+QwaXf8Ht6TlFxg09+S9wz0omw= github.com/ebitengine/purego v0.8.4/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= -github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM= -github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8= +github.com/gabriel-vasile/mimetype v1.4.10 h1:zyueNbySn/z8mJZHLt6IPw0KoZsiQNszIpU+bX4+ZK0= +github.com/gabriel-vasile/mimetype v1.4.10/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s= 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/gin-contrib/gzip v1.2.3 h1:dAhT722RuEG330ce2agAs75z7yB+NKvX/ZM1r8w0u2U= @@ -53,8 +56,8 @@ github.com/golang/mock v1.7.0-rc.1 h1:YojYx61/OLFsiv6Rw1Z96LpldJIy31o+UHmwAUMJ6/ github.com/golang/mock v1.7.0-rc.1/go.mod h1:s42URUywIqd+OcERslBJvOjepvNymP31m3q8d/GkuRs= 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 v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= -github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= +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/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -80,22 +83,22 @@ 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/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= +github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= -github.com/lufia/plan9stats v0.0.0-20250317134145-8bc96cf8fc35 h1:PpXWgLPs+Fqr325bN2FD2ISlRRztXibcX6e8f5FR5Dc= -github.com/lufia/plan9stats v0.0.0-20250317134145-8bc96cf8fc35/go.mod h1:autxFIvghDt3jPTLoqZ9OZ7s9qTGNAWmYCjVFWPX/zg= +github.com/lufia/plan9stats v0.0.0-20250827001030-24949be3fa54 h1:mFWunSatvkQQDhpdyuFAYwyAan3hzCuma+Pz8sqvOfg= +github.com/lufia/plan9stats v0.0.0-20250827001030-24949be3fa54/go.mod h1:autxFIvghDt3jPTLoqZ9OZ7s9qTGNAWmYCjVFWPX/zg= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-sqlite3 v1.14.30 h1:bVreufq3EAIG1Quvws73du3/QgdeZ3myglJlrzSYYCY= -github.com/mattn/go-sqlite3 v1.14.30/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= -github.com/miekg/dns v1.1.67 h1:kg0EHj0G4bfT5/oOys6HhZw4vmMlnoZ+gDu8tJ/AlI0= -github.com/miekg/dns v1.1.67/go.mod h1:fujopn7TB3Pu3JM69XaawiU0wqjpL9/8xGop5UrTPps= +github.com/mattn/go-sqlite3 v1.14.32 h1:JD12Ag3oLy1zQA+BNn74xRgaBbdhbNIDYvQUEuuErjs= +github.com/mattn/go-sqlite3 v1.14.32/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/miekg/dns v1.1.68 h1:jsSRkNozw7G/mnmXULynzMNIsgY2dHC8LO6U6Ij2JEA= +github.com/miekg/dns v1.1.68/go.mod h1:fujopn7TB3Pu3JM69XaawiU0wqjpL9/8xGop5UrTPps= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -127,14 +130,14 @@ github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= -github.com/sagernet/sing v0.5.1 h1:mhL/MZVq0TjuvHcpYcFtmSD1BFOxZ/+8ofbNZcg1k1Y= -github.com/sagernet/sing v0.5.1/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak= -github.com/sagernet/sing-shadowsocks v0.2.7 h1:zaopR1tbHEw5Nk6FAkM05wCslV6ahVegEZaKMv9ipx8= -github.com/sagernet/sing-shadowsocks v0.2.7/go.mod h1:0rIKJZBR65Qi0zwdKezt4s57y/Tl1ofkaq6NlkzVuyE= +github.com/sagernet/sing v0.7.10 h1:2yPhZFx+EkyHPH8hXNezgyRSHyGY12CboId7CtwLROw= +github.com/sagernet/sing v0.7.10/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak= +github.com/sagernet/sing-shadowsocks v0.2.9 h1:Paep5zCszRKsEn8587O0MnhFWKJwDW1Y4zOYYlIxMkM= +github.com/sagernet/sing-shadowsocks v0.2.9/go.mod h1:TE/Z6401Pi8tgr0nBZcM/xawAI6u3F6TTbz4nH/qw+8= 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/shirou/gopsutil/v4 v4.25.7 h1:bNb2JuqKuAu3tRlPv5piSmBZyMfecwQ+t/ILq+1JqVM= -github.com/shirou/gopsutil/v4 v4.25.7/go.mod h1:XV/egmwJtd3ZQjBpJVY5kndsiOO4IRqy9TQnmm6VP7U= +github.com/shirou/gopsutil/v4 v4.25.8 h1:NnAsw9lN7587WHxjJA9ryDnqhJpFH6A+wagYWTOH970= +github.com/shirou/gopsutil/v4 v4.25.8/go.mod h1:q9QdMmfAOVIw7a+eF86P7ISEU6ka+NLgkUxlopV4RwI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= @@ -143,80 +146,84 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -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/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/tklauser/go-sysconf v0.3.15 h1:VE89k0criAymJ/Os65CSn1IXaol+1wrsFHEB8Ol49K4= github.com/tklauser/go-sysconf v0.3.15/go.mod h1:Dmjwr6tYFIseJw7a3dRLJfsHAMXZ3nEnL/aZY+0IuI4= github.com/tklauser/numcpus v0.10.0 h1:18njr6LDBk1zuna922MgdjQuJFjrdppsZG60sHGfjso= github.com/tklauser/numcpus v0.10.0/go.mod h1:BiTKazU708GQTYF4mB+cmlpT2Is1gLk7XVuEeem8LsQ= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= -github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= -github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA= +github.com/ugorji/go/codec v1.3.0/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4= 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/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-20250725142056-5b52a03d4fb7 h1:Ript0vN+nSO33+Vj4n0mgNY5M+oOxFQJdrJ1VnwTBO0= -github.com/xtls/reality v0.0.0-20250725142056-5b52a03d4fb7/go.mod h1:XxvnCCgBee4WWE0bc4E+a7wbk8gkJ/rS0vNVNtC5qp0= -github.com/xtls/xray-core v1.250803.0 h1:sYdRC243UsujnePINH4IfM4MfHE4lj2p4wZFAfeE2GI= -github.com/xtls/xray-core v1.250803.0/go.mod h1:z2vn2o30flYEgpSz1iEhdZP1I46UZ3+gXINZyohH3yE= +github.com/xtls/reality v0.0.0-20250904214705-431b6ff8c67c h1:LHLhQY3mKXSpTcQAkjFR4/6ar3rXjQryNeM7khK3AHU= +github.com/xtls/reality v0.0.0-20250904214705-431b6ff8c67c/go.mod h1:XxvnCCgBee4WWE0bc4E+a7wbk8gkJ/rS0vNVNtC5qp0= +github.com/xtls/xray-core v1.250911.0 h1:KMN8zVurAjHFixiUoFV/jwmzYohf27dQRntjV+8LQno= +github.com/xtls/xray-core v1.250911.0/go.mod h1:LkqA/BFVtPS2e5fRzg/bkYas9nQu4Uztlx+/fjlLM9k= +github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU= +github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= 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.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg= -go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E= -go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE= -go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs= -go.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs= -go.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY= -go.opentelemetry.io/otel/sdk/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFwHX4dThiPis= -go.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4= -go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w= -go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA= +go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= +go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= +go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= +go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= +go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI= +go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg= +go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc= +go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps= +go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= +go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU= -go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM= +go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y= +go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU= 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/arch v0.19.0 h1:LmbDQUodHThXE+htjrnmVD73M//D9GTH6wFZjyDkjyU= -golang.org/x/arch v0.19.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk= -golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM= -golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY= -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.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs= -golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8= -golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= -golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/arch v0.21.0 h1:iTC9o7+wP6cPWpDWkivCvQFGAHDQ59SrSxsLPcnkArw= +golang.org/x/arch v0.21.0/go.mod h1:dNHoOeKiyja7GTvF9NJS1l3Z2yntpQNzgrjh1cU103A= +golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI= +golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8= +golang.org/x/mod v0.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U= +golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI= +golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I= +golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= +golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= +golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA= -golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4= -golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU= -golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ= -golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= -golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo= -golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg= +golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= +golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= +golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= +golang.org/x/time v0.13.0 h1:eUlYslOIt32DgYD6utsuUeHs4d7AsEYLuIAdg7FlYgI= +golang.org/x/time v0.13.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= +golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE= +golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w= 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/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a h1:v2PbRU4K3llS09c7zodFpNePeamkAwG3mPrAery9VeE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= -google.golang.org/grpc v1.74.2 h1:WoosgB65DlWVC9FqI82dGsZhWFNBSLjQ84bjROOpMu4= -google.golang.org/grpc v1.74.2/go.mod h1:CtQ+BGjaAIXHs/5YS3i473GqwBBa1zGQNevxdeBEXrM= -google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= -google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +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= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250908214217-97024824d090 h1:/OQuEa4YWtDt7uQWHd3q3sUMb+QOLQUg1xa8CEsRv5w= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250908214217-97024824d090/go.mod h1:GmFNa4BdJZ2a8G+wCe9Bg3wwThLrJun751XstdJt5Og= +google.golang.org/grpc v1.75.1 h1:/ODCNEuf9VghjgO3rqLcfg8fiOP0nSluljWFlDxELLI= +google.golang.org/grpc v1.75.1/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= +google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw= +google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= @@ -228,9 +235,9 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gorm.io/driver/sqlite v1.6.0 h1:WHRRrIiulaPiPFmDcod6prc4l2VGVWHz80KspNsxSfQ= gorm.io/driver/sqlite v1.6.0/go.mod h1:AO9V1qIQddBESngQUKWL9yoH93HIeA1X6V633rBwyT8= -gorm.io/gorm v1.30.1 h1:lSHg33jJTBxs2mgJRfRZeLDG+WZaHYCk3Wtfl6Ngzo4= -gorm.io/gorm v1.30.1/go.mod h1:8Z33v652h4//uMA76KjeDH8mJXPm1QNCYrMeatR0DOE= -gvisor.dev/gvisor v0.0.0-20250428193742-2d800c3129d5 h1:sfK5nHuG7lRFZ2FdTT3RimOqWBg8IrVm+/Vko1FVOsk= -gvisor.dev/gvisor v0.0.0-20250428193742-2d800c3129d5/go.mod h1:3r5CMtNQMKIvBlrmM9xWUNamjKBYPOWyXOjmg5Kts3g= +gorm.io/gorm v1.31.0 h1:0VlycGreVhK7RF/Bwt51Fk8v0xLiiiFdbGDPIZQ7mJY= +gorm.io/gorm v1.31.0/go.mod h1:XyQVbO2k6YkOis7C2437jSit3SsDK72s7n7rsSHd+Gs= +gvisor.dev/gvisor v0.0.0-20250503011706-39ed1f5ac29c h1:m/r7OM+Y2Ty1sgBQ7Qb27VgIMBW8ZZhT4gLnUyDIhzI= +gvisor.dev/gvisor v0.0.0-20250503011706-39ed1f5ac29c/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= diff --git a/sub/subJsonService.go b/sub/subJsonService.go index 055a924f..360067eb 100644 --- a/sub/subJsonService.go +++ b/sub/subJsonService.go @@ -184,8 +184,14 @@ func (s *SubJsonService) getConfig(inbound *model.Inbound, client model.Client, var newOutbounds []json_util.RawMessage switch inbound.Protocol { - case "vmess", "vless": - newOutbounds = append(newOutbounds, s.genVnext(inbound, streamSettings, client)) + case "vmess": + newOutbounds = append(newOutbounds, s.genVnext(inbound, streamSettings, client, "")) + case "vless": + var vlessSettings model.VLESSSettings + _ = json.Unmarshal([]byte(inbound.Settings), &vlessSettings) + + newOutbounds = append(newOutbounds, + s.genVnext(inbound, streamSettings, client, vlessSettings.Encryption)) case "trojan", "shadowsocks": newOutbounds = append(newOutbounds, s.genServer(inbound, streamSettings, client)) } @@ -283,7 +289,7 @@ func (s *SubJsonService) realityData(rData map[string]interface{}) map[string]in return rltyData } -func (s *SubJsonService) genVnext(inbound *model.Inbound, streamSettings json_util.RawMessage, client model.Client) json_util.RawMessage { +func (s *SubJsonService) genVnext(inbound *model.Inbound, streamSettings json_util.RawMessage, client model.Client, encryption string) json_util.RawMessage { outbound := Outbound{} usersData := make([]UserVnext, 1) @@ -291,7 +297,7 @@ func (s *SubJsonService) genVnext(inbound *model.Inbound, streamSettings json_ut usersData[0].Level = 8 if inbound.Protocol == model.VLESS { usersData[0].Flow = client.Flow - usersData[0].Encryption = "none" + usersData[0].Encryption = encryption } vnextData := make([]VnextSetting, 1) diff --git a/sub/subService.go b/sub/subService.go index d9698729..601aeecf 100644 --- a/sub/subService.go +++ b/sub/subService.go @@ -305,6 +305,9 @@ func (s *SubService) genVlessLink(inbound *model.Inbound, email string) string { if inbound.Protocol != model.VLESS { return "" } + var vlessSettings model.VLESSSettings + _ = json.Unmarshal([]byte(inbound.Settings), &vlessSettings) + var stream map[string]interface{} json.Unmarshal([]byte(inbound.StreamSettings), &stream) clients, _ := s.inboundService.GetClients(inbound) @@ -319,6 +322,9 @@ func (s *SubService) genVlessLink(inbound *model.Inbound, email string) string { port := inbound.Port streamNetwork := stream["network"].(string) params := make(map[string]string) + if vlessSettings.Encryption != "" { + params["encryption"] = vlessSettings.Encryption + } params["type"] = streamNetwork switch streamNetwork { diff --git a/web/assets/js/model/inbound.js b/web/assets/js/model/inbound.js index 1e993c13..ddf982ac 100644 --- a/web/assets/js/model/inbound.js +++ b/web/assets/js/model/inbound.js @@ -11,10 +11,8 @@ const Protocols = { const SSMethods = { AES_256_GCM: 'aes-256-gcm', - AES_128_GCM: 'aes-128-gcm', CHACHA20_POLY1305: 'chacha20-poly1305', CHACHA20_IETF_POLY1305: 'chacha20-ietf-poly1305', - XCHACHA20_POLY1305: 'xchacha20-poly1305', XCHACHA20_IETF_POLY1305: 'xchacha20-ietf-poly1305', BLAKE3_AES_128_GCM: '2022-blake3-aes-128-gcm', BLAKE3_AES_256_GCM: '2022-blake3-aes-256-gcm', @@ -1139,8 +1137,8 @@ class Inbound extends XrayCommonClass { get isSSMultiUser() { return this.method != SSMethods.BLAKE3_CHACHA20_POLY1305; } - get isSS2022(){ - return this.method.substring(0,4) === "2022"; + get isSS2022() { + return this.method.substring(0, 4) === "2022"; } get serverName() { @@ -1307,6 +1305,7 @@ class Inbound extends XrayCommonClass { const security = forceTls == 'same' ? this.stream.security : forceTls; const params = new Map(); params.set("type", this.stream.network); + params.set("encryption", this.settings.encryption); switch (type) { case "tcp": const tcp = this.stream.tcp; @@ -1748,7 +1747,7 @@ Inbound.Settings = class extends XrayCommonClass { Inbound.VmessSettings = class extends Inbound.Settings { constructor(protocol, - vmesses=[new Inbound.VmessSettings.Vmess()]) { + vmesses = [new Inbound.VmessSettings.Vmess()]) { super(protocol); this.vmesses = vmesses; } @@ -1771,7 +1770,7 @@ Inbound.VmessSettings = class extends Inbound.Settings { } } - static fromJson(json={}) { + static fromJson(json = {}) { return new Inbound.VmessSettings( Protocols.VMESS, json.clients.map(client => Inbound.VmessSettings.Vmess.fromJson(client)), @@ -1853,13 +1852,17 @@ Inbound.VLESSSettings = class extends Inbound.Settings { constructor( protocol, vlesses = [new Inbound.VLESSSettings.VLESS()], - decryption = 'none', - fallbacks = [] + decryption = "none", + encryption = "none", + fallbacks = [], + selectedAuth = undefined, ) { super(protocol); this.vlesses = vlesses; this.decryption = decryption; + this.encryption = encryption; this.fallbacks = fallbacks; + this.selectedAuth = selectedAuth; } addFallback() { @@ -1870,21 +1873,40 @@ Inbound.VLESSSettings = class extends Inbound.Settings { this.fallbacks.splice(index, 1); } - // decryption should be set to static value static fromJson(json = {}) { - return new Inbound.VLESSSettings( + const obj = new Inbound.VLESSSettings( Protocols.VLESS, - json.clients.map(client => Inbound.VLESSSettings.VLESS.fromJson(client)), - json.decryption || 'none', - Inbound.VLESSSettings.Fallback.fromJson(json.fallbacks),); + (json.clients || []).map(client => Inbound.VLESSSettings.VLESS.fromJson(client)), + json.decryption, + json.encryption, + Inbound.VLESSSettings.Fallback.fromJson(json.fallbacks || []), + json.selectedAuth + ); + return obj; } + toJson() { - return { + const json = { clients: Inbound.VLESSSettings.toJsonArray(this.vlesses), - decryption: this.decryption, - fallbacks: Inbound.VLESSSettings.toJsonArray(this.fallbacks), }; + + if (this.decryption) { + json.decryption = this.decryption; + } + + if (this.encryption) { + json.encryption = this.encryption; + } + + if (this.fallbacks && this.fallbacks.length > 0) { + json.fallbacks = Inbound.VLESSSettings.toJsonArray(this.fallbacks); + } + if (this.selectedAuth) { + json.selectedAuth = this.selectedAuth; + } + + return json; } }; @@ -1952,7 +1974,7 @@ Inbound.VLESSSettings.VLESS = class extends XrayCommonClass { } }; Inbound.VLESSSettings.Fallback = class extends XrayCommonClass { - constructor(name='', alpn='', path='', dest='', xver=0) { + constructor(name = '', alpn = '', path = '', dest = '', xver = 0) { super(); this.name = name; this.alpn = alpn; @@ -2098,7 +2120,7 @@ Inbound.TrojanSettings.Trojan = class extends XrayCommonClass { }; Inbound.TrojanSettings.Fallback = class extends XrayCommonClass { - constructor(name='', alpn='', path='', dest='', xver=0) { + constructor(name = '', alpn = '', path = '', dest = '', xver = 0) { super(); this.name = name; this.alpn = alpn; @@ -2404,20 +2426,20 @@ Inbound.WireguardSettings = class extends XrayCommonClass { super(protocol); this.mtu = mtu; this.secretKey = secretKey; - this.pubKey = secretKey.length>0 ? Wireguard.generateKeypair(secretKey).publicKey : ''; + this.pubKey = secretKey.length > 0 ? Wireguard.generateKeypair(secretKey).publicKey : ''; this.peers = peers; this.kernelMode = kernelMode; } addPeer() { - this.peers.push(new Inbound.WireguardSettings.Peer(null,null,'',['10.0.0.' + (this.peers.length+2)])); + this.peers.push(new Inbound.WireguardSettings.Peer(null, null, '', ['10.0.0.' + (this.peers.length + 2)])); } delPeer(index) { this.peers.splice(index, 1); } - static fromJson(json={}){ + static fromJson(json = {}) { return new Inbound.WireguardSettings( Protocols.WIREGUARD, json.mtu, @@ -2429,7 +2451,7 @@ Inbound.WireguardSettings = class extends XrayCommonClass { toJson() { return { - mtu: this.mtu?? undefined, + mtu: this.mtu ?? undefined, secretKey: this.secretKey, peers: Inbound.WireguardSettings.Peer.toJsonArray(this.peers), kernelMode: this.kernelMode, @@ -2438,16 +2460,16 @@ Inbound.WireguardSettings = class extends XrayCommonClass { }; Inbound.WireguardSettings.Peer = class extends XrayCommonClass { - constructor(privateKey, publicKey, psk='', allowedIPs=['10.0.0.2/32'], keepAlive=0) { + constructor(privateKey, publicKey, psk = '', allowedIPs = ['10.0.0.2/32'], keepAlive = 0) { super(); this.privateKey = privateKey this.publicKey = publicKey; - if (!this.publicKey){ + if (!this.publicKey) { [this.publicKey, this.privateKey] = Object.values(Wireguard.generateKeypair()) } this.psk = psk; - allowedIPs.forEach((a,index) => { - if (a.length>0 && !a.includes('/')) allowedIPs[index] += '/32'; + allowedIPs.forEach((a, index) => { + if (a.length > 0 && !a.includes('/')) allowedIPs[index] += '/32'; }) this.allowedIPs = allowedIPs; this.keepAlive = keepAlive; diff --git a/web/assets/js/model/outbound.js b/web/assets/js/model/outbound.js index 8f1f24a6..a298c75c 100644 --- a/web/assets/js/model/outbound.js +++ b/web/assets/js/model/outbound.js @@ -13,10 +13,8 @@ const Protocols = { const SSMethods = { AES_256_GCM: 'aes-256-gcm', - AES_128_GCM: 'aes-128-gcm', CHACHA20_POLY1305: 'chacha20-poly1305', CHACHA20_IETF_POLY1305: 'chacha20-ietf-poly1305', - XCHACHA20_POLY1305: 'xchacha20-poly1305', XCHACHA20_IETF_POLY1305: 'xchacha20-ietf-poly1305', BLAKE3_AES_128_GCM: '2022-blake3-aes-128-gcm', BLAKE3_AES_256_GCM: '2022-blake3-aes-256-gcm', @@ -813,7 +811,7 @@ class Outbound extends CommonClass { var settings; switch (protocol) { case Protocols.VLESS: - settings = new Outbound.VLESSSettings(address, port, userData, url.searchParams.get('flow') ?? ''); + settings = new Outbound.VLESSSettings(address, port, userData, url.searchParams.get('flow') ?? '', url.searchParams.get('encryption') ?? 'none'); break; case Protocols.Trojan: settings = new Outbound.TrojanSettings(address, port, userData); @@ -1039,13 +1037,13 @@ Outbound.VmessSettings = class extends CommonClass { } }; Outbound.VLESSSettings = class extends CommonClass { - constructor(address, port, id, flow, encryption = 'none') { + constructor(address, port, id, flow, encryption) { super(); this.address = address; this.port = port; this.id = id; this.flow = flow; - this.encryption = encryption + this.encryption = encryption; } static fromJson(json = {}) { @@ -1064,7 +1062,7 @@ Outbound.VLESSSettings = class extends CommonClass { vnext: [{ address: this.address, port: this.port, - users: [{ id: this.id, flow: this.flow, encryption: 'none', }], + users: [{ id: this.id, flow: this.flow, encryption: this.encryption }], }], }; } diff --git a/web/controller/server.go b/web/controller/server.go index 25279def..7367f5a4 100644 --- a/web/controller/server.go +++ b/web/controller/server.go @@ -39,6 +39,9 @@ func (a *ServerController) initRouter(g *gin.RouterGroup) { g = g.Group("/server") g.Use(a.checkLogin) + g.GET("/getDb", a.getDb) + g.GET("/getNewVlessEnc", a.getNewVlessEnc) + g.POST("/status", a.status) g.POST("/getXrayVersion", a.getXrayVersion) g.POST("/stopXrayService", a.stopXrayService) @@ -46,7 +49,6 @@ func (a *ServerController) initRouter(g *gin.RouterGroup) { g.POST("/installXray/:version", a.installXray) g.POST("/logs/:count", a.getLogs) g.POST("/getConfigJson", a.getConfigJson) - g.GET("/getDb", a.getDb) g.POST("/importDB", a.importDB) g.POST("/getNewX25519Cert", a.getNewX25519Cert) g.POST("/getNewmldsa65", a.getNewmldsa65) @@ -207,3 +209,12 @@ func (a *ServerController) getNewEchCert(c *gin.Context) { } jsonObj(c, cert, nil) } + +func (a *ServerController) getNewVlessEnc(c *gin.Context) { + out, err := a.serverService.GetNewVlessEnc() + if err != nil { + jsonMsg(c, "Failed to generate vless encryption config", err) + return + } + jsonObj(c, out, nil) +} diff --git a/web/html/xui/form/outbound.html b/web/html/xui/form/outbound.html index 8c679ebf..090e5195 100644 --- a/web/html/xui/form/outbound.html +++ b/web/html/xui/form/outbound.html @@ -211,6 +211,11 @@ + diff --git a/web/html/xui/inbound_modal.html b/web/html/xui/inbound_modal.html index 1b3810ca..4815f2fc 100644 --- a/web/html/xui/inbound_modal.html +++ b/web/html/xui/inbound_modal.html @@ -132,6 +132,10 @@ inModal.inbound.stream.reality.privateKey = msg.obj.privateKey; inModal.inbound.stream.reality.settings.publicKey = msg.obj.publicKey; }, + clearX25519Cert() { + this.inbound.stream.reality.privateKey = ''; + this.inbound.stream.reality.settings.publicKey = ''; + }, async getNewmldsa65() { inModal.loading(true); const msg = await HttpUtil.post('/server/getNewmldsa65'); @@ -142,6 +146,10 @@ inModal.inbound.stream.reality.mldsa65Seed = msg.obj.seed; inModal.inbound.stream.reality.settings.mldsa65Verify = msg.obj.verify; }, + clearMldsa65() { + this.inbound.stream.reality.mldsa65Seed = ''; + this.inbound.stream.reality.settings.mldsa65Verify = ''; + }, async getNewEchCert() { inModal.loading(true); const msg = await HttpUtil.post('/server/getNewEchCert', {sni: inModal.inbound.stream.tls.sni}); @@ -152,6 +160,36 @@ inModal.inbound.stream.tls.echServerKeys = msg.obj.echServerKeys; inModal.inbound.stream.tls.settings.echConfigList = msg.obj.echConfigList; }, + clearEchCert() { + this.inbound.stream.tls.echServerKeys = ''; + this.inbound.stream.tls.settings.echConfigList = ''; + }, + async getNewVlessEnc() { + inModal.loading(true); + const msg = await HttpUtil.get('/server/getNewVlessEnc'); + inModal.loading(false); + + if (!msg.success) { + return; + } + + const auths = msg.obj.auths || []; + const selected = inModal.inbound.settings.selectedAuth; + const block = auths.find(a => a.label === selected); + + if (!block) { + console.error("No auth block for", selected); + return; + } + + inModal.inbound.settings.decryption = block.decryption; + inModal.inbound.settings.encryption = block.encryption; + }, + clearVlessEnc() { + this.inbound.settings.decryption = 'none'; + this.inbound.settings.encryption = 'none'; + this.inbound.settings.selectedAuth = undefined; + } }, }); diff --git a/web/service/server.go b/web/service/server.go index e7ec0704..a45b8d2c 100644 --- a/web/service/server.go +++ b/web/service/server.go @@ -11,6 +11,7 @@ import ( "net/http" "os" "os/exec" + "path/filepath" "runtime" "strconv" "strings" @@ -279,6 +280,8 @@ func (s *ServerService) downloadXRay(version string) (string, error) { switch osName { case "darwin": osName = "macos" + case "windows": + osName = "windows" } switch arch { @@ -322,19 +325,23 @@ func (s *ServerService) downloadXRay(version string) (string, error) { } func (s *ServerService) UpdateXray(version string) error { + // 1. Stop xray before doing anything + if err := s.StopXrayService(); err != nil { + logger.Warning("failed to stop xray before update:", err) + } + + // 2. Download the zip zipFileName, err := s.downloadXRay(version) if err != nil { return err } + defer os.Remove(zipFileName) zipFile, err := os.Open(zipFileName) if err != nil { return err } - defer func() { - zipFile.Close() - os.Remove(zipFileName) - }() + defer zipFile.Close() stat, err := zipFile.Stat() if err != nil { @@ -345,19 +352,14 @@ func (s *ServerService) UpdateXray(version string) error { return err } - s.xrayService.StopXray() - defer func() { - err := s.xrayService.RestartXray(true) - if err != nil { - logger.Error("start xray failed:", err) - } - }() - + // 3. Helper to extract files copyZipFile := func(zipName string, fileName string) error { zipFile, err := reader.Open(zipName) if err != nil { return err } + defer zipFile.Close() + os.MkdirAll(filepath.Dir(fileName), 0755) os.Remove(fileName) file, err := os.OpenFile(fileName, os.O_CREATE|os.O_RDWR|os.O_TRUNC, fs.ModePerm) if err != nil { @@ -368,11 +370,23 @@ func (s *ServerService) UpdateXray(version string) error { return err } - err = copyZipFile("xray", xray.GetBinaryPath()) + // 4. Extract correct binary + if runtime.GOOS == "windows" { + targetBinary := filepath.Join("bin", "xray-windows-amd64.exe") + err = copyZipFile("xray.exe", targetBinary) + } else { + err = copyZipFile("xray", xray.GetBinaryPath()) + } if err != nil { return err } + // 5. Restart xray + if err := s.xrayService.RestartXray(true); err != nil { + logger.Error("start xray failed:", err) + return err + } + return nil } @@ -614,3 +628,43 @@ func (s *ServerService) GetNewEchCert(sni string) (interface{}, error) { "echConfigList": configList, }, nil } + +func (s *ServerService) GetNewVlessEnc() (any, error) { + cmd := exec.Command(xray.GetBinaryPath(), "vlessenc") + var out bytes.Buffer + cmd.Stdout = &out + if err := cmd.Run(); err != nil { + return nil, err + } + + lines := strings.Split(out.String(), "\n") + var auths []map[string]string + var current map[string]string + + for _, line := range lines { + line = strings.TrimSpace(line) + if strings.HasPrefix(line, "Authentication:") { + if current != nil { + auths = append(auths, current) + } + current = map[string]string{ + "label": strings.TrimSpace(strings.TrimPrefix(line, "Authentication:")), + } + } else if strings.HasPrefix(line, `"decryption"`) || strings.HasPrefix(line, `"encryption"`) { + parts := strings.SplitN(line, ":", 2) + if len(parts) == 2 && current != nil { + key := strings.Trim(parts[0], `" `) + val := strings.Trim(parts[1], `" `) + current[key] = val + } + } + } + + if current != nil { + auths = append(auths, current) + } + + return map[string]any{ + "auths": auths, + }, nil +} diff --git a/web/service/xray.go b/web/service/xray.go index 849d3c2b..a896f692 100644 --- a/web/service/xray.go +++ b/web/service/xray.go @@ -3,6 +3,7 @@ package service import ( "encoding/json" "errors" + "runtime" "sync" "x-ui/logger" @@ -32,7 +33,16 @@ func (s *XrayService) GetXrayErr() error { if p == nil { return nil } - return p.GetErr() + + err := p.GetErr() + + if runtime.GOOS == "windows" && err.Error() == "exit status 1" { + // exit status 1 on Windows means that Xray process was killed + // as we kill process to stop in on Windows, this is not an error + return nil + } + + return err } func (s *XrayService) GetXrayResult() string { @@ -45,7 +55,15 @@ func (s *XrayService) GetXrayResult() string { if p == nil { return "" } + result = p.GetResult() + + if runtime.GOOS == "windows" && result == "exit status 1" { + // exit status 1 on Windows means that Xray process was killed + // as we kill process to stop in on Windows, this is not an error + return "" + } + return result } diff --git a/windows_files/SSL/Win64OpenSSL_Light-3_5_2.exe b/windows_files/SSL/Win64OpenSSL_Light-3_5_2.exe new file mode 100644 index 00000000..a93dc62a Binary files /dev/null and b/windows_files/SSL/Win64OpenSSL_Light-3_5_2.exe differ diff --git a/windows_files/readme.txt b/windows_files/readme.txt new file mode 100644 index 00000000..16219da8 --- /dev/null +++ b/windows_files/readme.txt @@ -0,0 +1,12 @@ +we don't have bash menu for windows +if you forgot your password you need to check your database with https://sqlitebrowser.org/ +the app need to be open all the time + +default setting: +http://localhost:2053/ +user: admin +pass: admin +port: 2053 + + +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout localhost.key -out localhost.crt diff --git a/xray/log_writer.go b/xray/log_writer.go index 24d22f2c..b6e04db7 100644 --- a/xray/log_writer.go +++ b/xray/log_writer.go @@ -32,32 +32,56 @@ func (lw *LogWriter) Write(m []byte) (n int, err error) { return len(m), nil } - regex := regexp.MustCompile(`^(\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2}) \[([^\]]+)\] (.+)$`) - messages := strings.Split(message, "\n") + regex := regexp.MustCompile(`^(\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2}\.\d{6}) \[([^\]]+)\] (.+)$`) + messages := strings.SplitSeq(message, "\n") - for _, msg := range messages { + for msg := range messages { matches := regex.FindStringSubmatch(msg) if len(matches) > 3 { level := matches[2] msgBody := matches[3] + msgBodyLower := strings.ToLower(msgBody) - // Map the level to the appropriate logger function - switch level { - case "Debug": + if strings.Contains(msgBodyLower, "tls handshake error") || + strings.Contains(msgBodyLower, "connection ends") { logger.Debug("XRAY: " + msgBody) - case "Info": - logger.Info("XRAY: " + msgBody) - case "Warning": - logger.Warning("XRAY: " + msgBody) - case "Error": + lw.lastLine = "" + continue + } + + if strings.Contains(msgBodyLower, "failed") { logger.Error("XRAY: " + msgBody) - default: - logger.Debug("XRAY: " + msg) + } else { + switch level { + case "Debug": + logger.Debug("XRAY: " + msgBody) + case "Info": + logger.Info("XRAY: " + msgBody) + case "Warning": + logger.Warning("XRAY: " + msgBody) + case "Error": + logger.Error("XRAY: " + msgBody) + default: + logger.Debug("XRAY: " + msg) + } } lw.lastLine = "" } else if msg != "" { - logger.Debug("XRAY: " + msg) + msgLower := strings.ToLower(msg) + + if strings.Contains(msgLower, "tls handshake error") || + strings.Contains(msgLower, "connection ends") { + logger.Debug("XRAY: " + msg) + lw.lastLine = msg + continue + } + + if strings.Contains(msgLower, "failed") { + logger.Error("XRAY: " + msg) + } else { + logger.Debug("XRAY: " + msg) + } lw.lastLine = msg } } diff --git a/xray/process.go b/xray/process.go index 8dc9dbab..56549292 100644 --- a/xray/process.go +++ b/xray/process.go @@ -189,7 +189,12 @@ func (p *process) Stop() error { if !p.IsRunning() { return errors.New("xray is not running") } - return p.cmd.Process.Signal(syscall.SIGTERM) + + if runtime.GOOS == "windows" { + return p.cmd.Process.Kill() + } else { + return p.cmd.Process.Signal(syscall.SIGTERM) + } } func writeCrashReport(m []byte) error {