mirror of
https://github.com/XTLS/Xray-core.git
synced 2025-08-23 01:56:48 +08:00
Compare commits
28 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
1bf3a632ca | ||
![]() |
ff5ce767df | ||
![]() |
8c0d3c0257 | ||
![]() |
9bc1564b0a | ||
![]() |
6a85682716 | ||
![]() |
6f61021f7a | ||
![]() |
c0ceebe709 | ||
![]() |
eaf401eda9 | ||
![]() |
11ec77bc76 | ||
![]() |
3b2ff95a9b | ||
![]() |
3db7d44fc2 | ||
![]() |
c4fbdf1b78 | ||
![]() |
c9b6fc0104 | ||
![]() |
d7ac6946d2 | ||
![]() |
48a75fc340 | ||
![]() |
a55cf1d0bf | ||
![]() |
f35ded79ad | ||
![]() |
f3104b8684 | ||
![]() |
bc4de6a026 | ||
![]() |
3e4e050313 | ||
![]() |
b8e8229242 | ||
![]() |
a8fa5bf516 | ||
![]() |
4a3f3ef775 | ||
![]() |
5858726233 | ||
![]() |
b13c3f053a | ||
![]() |
2e30093ffd | ||
![]() |
1d7c40d728 | ||
![]() |
143229b148 |
34
.github/workflows/release.yml
vendored
34
.github/workflows/release.yml
vendored
@@ -161,21 +161,25 @@ jobs:
|
|||||||
mv xray xray.exe
|
mv xray xray.exe
|
||||||
|
|
||||||
- name: Prepare to release
|
- name: Prepare to release
|
||||||
run: |
|
uses: nick-fields/retry@v2
|
||||||
cp ${GITHUB_WORKSPACE}/README.md ./build_assets/README.md
|
with:
|
||||||
cp ${GITHUB_WORKSPACE}/LICENSE ./build_assets/LICENSE
|
timeout_minutes: 60
|
||||||
LIST=('geoip geoip geoip' 'domain-list-community dlc geosite')
|
retry_wait_seconds: 60
|
||||||
for i in "${LIST[@]}"
|
max_attempts: 60
|
||||||
do
|
command: |
|
||||||
INFO=($(echo $i | awk 'BEGIN{FS=" ";OFS=" "} {print $1,$2,$3}'))
|
cp ${GITHUB_WORKSPACE}/README.md ./build_assets/README.md
|
||||||
LASTEST_TAG="$(curl -sL "https://api.github.com/repos/v2fly/${INFO[0]}/releases" | jq -r ".[0].tag_name" || echo "latest")"
|
cp ${GITHUB_WORKSPACE}/LICENSE ./build_assets/LICENSE
|
||||||
FILE_NAME="${INFO[2]}.dat"
|
LIST=('geoip geoip geoip' 'domain-list-community dlc geosite')
|
||||||
echo -e "Downloading ${FILE_NAME}..."
|
for i in "${LIST[@]}"
|
||||||
curl -L "https://github.com/v2fly/${INFO[0]}/releases/download/${LASTEST_TAG}/${INFO[1]}.dat" -o ./build_assets/${FILE_NAME}
|
do
|
||||||
echo -e "Verifying HASH key..."
|
INFO=($(echo $i | awk 'BEGIN{FS=" ";OFS=" "} {print $1,$2,$3}'))
|
||||||
HASH="$(curl -sL "https://github.com/v2fly/${INFO[0]}/releases/download/${LASTEST_TAG}/${INFO[1]}.dat.sha256sum" | awk -F ' ' '{print $1}')"
|
FILE_NAME="${INFO[2]}.dat"
|
||||||
[ "$(sha256sum "./build_assets/${FILE_NAME}" | awk -F ' ' '{print $1}')" == "${HASH}" ] || { echo -e "The HASH key of ${FILE_NAME} does not match cloud one."; exit 1; }
|
echo -e "Downloading https://raw.githubusercontent.com/v2fly/${INFO[0]}/release/${INFO[1]}.dat..."
|
||||||
done
|
curl -L "https://raw.githubusercontent.com/v2fly/${INFO[0]}/release/${INFO[1]}.dat" -o ./build_assets/${FILE_NAME}
|
||||||
|
echo -e "Verifying HASH key..."
|
||||||
|
HASH="$(curl -sL "https://raw.githubusercontent.com/v2fly/${INFO[0]}/release/${INFO[1]}.dat.sha256sum" | awk -F ' ' '{print $1}')"
|
||||||
|
[ "$(sha256sum "./build_assets/${FILE_NAME}" | awk -F ' ' '{print $1}')" == "${HASH}" ] || { echo -e "The HASH key of ${FILE_NAME} does not match cloud one."; exit 1; }
|
||||||
|
done
|
||||||
|
|
||||||
- name: Create ZIP archive
|
- name: Create ZIP archive
|
||||||
shell: bash
|
shell: bash
|
||||||
|
@@ -7,8 +7,8 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/xtls/xray-core/common"
|
"github.com/xtls/xray-core/common"
|
||||||
"github.com/xtls/xray-core/common/log"
|
|
||||||
"github.com/xtls/xray-core/common/errors"
|
"github.com/xtls/xray-core/common/errors"
|
||||||
|
"github.com/xtls/xray-core/common/log"
|
||||||
"github.com/xtls/xray-core/common/net"
|
"github.com/xtls/xray-core/common/net"
|
||||||
"github.com/xtls/xray-core/common/session"
|
"github.com/xtls/xray-core/common/session"
|
||||||
"github.com/xtls/xray-core/core"
|
"github.com/xtls/xray-core/core"
|
||||||
|
@@ -355,6 +355,7 @@ func (m *ClientWorker) handleStatusEnd(meta *FrameMetadata, reader *buf.Buffered
|
|||||||
common.Interrupt(s.input)
|
common.Interrupt(s.input)
|
||||||
common.Interrupt(s.output)
|
common.Interrupt(s.output)
|
||||||
}
|
}
|
||||||
|
common.Interrupt(s.input)
|
||||||
s.Close()
|
s.Close()
|
||||||
}
|
}
|
||||||
if meta.Option.Has(OptionData) {
|
if meta.Option.Has(OptionData) {
|
||||||
|
@@ -202,6 +202,7 @@ func (w *ServerWorker) handleStatusEnd(meta *FrameMetadata, reader *buf.Buffered
|
|||||||
common.Interrupt(s.input)
|
common.Interrupt(s.input)
|
||||||
common.Interrupt(s.output)
|
common.Interrupt(s.output)
|
||||||
}
|
}
|
||||||
|
common.Interrupt(s.input)
|
||||||
s.Close()
|
s.Close()
|
||||||
}
|
}
|
||||||
if meta.Option.Has(OptionData) {
|
if meta.Option.Has(OptionData) {
|
||||||
|
@@ -26,7 +26,8 @@ func MustFromContext(ctx context.Context) *Instance {
|
|||||||
return x
|
return x
|
||||||
}
|
}
|
||||||
|
|
||||||
/* toContext returns ctx from the given context, or creates an Instance if the context doesn't find that.
|
/*
|
||||||
|
toContext returns ctx from the given context, or creates an Instance if the context doesn't find that.
|
||||||
|
|
||||||
It is unsupported to use this function to create a context that is suitable to invoke Xray's internal component
|
It is unsupported to use this function to create a context that is suitable to invoke Xray's internal component
|
||||||
in third party code, you shouldn't use //go:linkname to alias of this function into your own package and
|
in third party code, you shouldn't use //go:linkname to alias of this function into your own package and
|
||||||
@@ -34,7 +35,6 @@ use this function in your third party code.
|
|||||||
|
|
||||||
For third party code, usage enabled by creating a context to interact with Xray's internal component is unsupported,
|
For third party code, usage enabled by creating a context to interact with Xray's internal component is unsupported,
|
||||||
and may break at any time.
|
and may break at any time.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
func toContext(ctx context.Context, v *Instance) context.Context {
|
func toContext(ctx context.Context, v *Instance) context.Context {
|
||||||
if FromContext(ctx) != v {
|
if FromContext(ctx) != v {
|
||||||
@@ -43,7 +43,8 @@ func toContext(ctx context.Context, v *Instance) context.Context {
|
|||||||
return ctx
|
return ctx
|
||||||
}
|
}
|
||||||
|
|
||||||
/*ToBackgroundDetachedContext create a detached context from another context
|
/*
|
||||||
|
ToBackgroundDetachedContext create a detached context from another context
|
||||||
Internal API
|
Internal API
|
||||||
*/
|
*/
|
||||||
func ToBackgroundDetachedContext(ctx context.Context) context.Context {
|
func ToBackgroundDetachedContext(ctx context.Context) context.Context {
|
||||||
|
@@ -18,7 +18,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
version = "1.6.5"
|
version = "1.7.2"
|
||||||
build = "Custom"
|
build = "Custom"
|
||||||
codename = "Xray, Penetrates Everything."
|
codename = "Xray, Penetrates Everything."
|
||||||
intro = "A unified platform for anti-censorship."
|
intro = "A unified platform for anti-censorship."
|
||||||
|
35
go.mod
35
go.mod
@@ -8,24 +8,24 @@ require (
|
|||||||
github.com/golang/protobuf v1.5.2
|
github.com/golang/protobuf v1.5.2
|
||||||
github.com/google/go-cmp v0.5.9
|
github.com/google/go-cmp v0.5.9
|
||||||
github.com/gorilla/websocket v1.5.0
|
github.com/gorilla/websocket v1.5.0
|
||||||
github.com/lucas-clemente/quic-go v0.31.0
|
github.com/lucas-clemente/quic-go v0.31.1
|
||||||
github.com/marten-seemann/qtls-go1-18 v0.1.3
|
github.com/marten-seemann/qtls-go1-18 v0.1.4
|
||||||
github.com/miekg/dns v1.1.50
|
github.com/miekg/dns v1.1.50
|
||||||
github.com/pelletier/go-toml v1.9.5
|
github.com/pelletier/go-toml v1.9.5
|
||||||
github.com/pires/go-proxyproto v0.6.2
|
github.com/pires/go-proxyproto v0.6.2
|
||||||
github.com/refraction-networking/utls v1.2.0
|
github.com/refraction-networking/utls v1.2.0
|
||||||
github.com/sagernet/sing v0.1.0
|
github.com/sagernet/sing v0.1.2
|
||||||
github.com/sagernet/sing-shadowsocks v0.1.0
|
github.com/sagernet/sing-shadowsocks v0.1.0
|
||||||
github.com/sagernet/wireguard-go v0.0.0-20221116151939-c99467f53f2c
|
github.com/sagernet/wireguard-go v0.0.0-20221116151939-c99467f53f2c
|
||||||
github.com/seiflotfy/cuckoofilter v0.0.0-20220411075957-e3b120b3f5fb
|
github.com/seiflotfy/cuckoofilter v0.0.0-20220411075957-e3b120b3f5fb
|
||||||
github.com/stretchr/testify v1.8.1
|
github.com/stretchr/testify v1.8.1
|
||||||
github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e
|
github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e
|
||||||
github.com/xtls/go v0.0.0-20220914232946-0441cf4cf837
|
github.com/xtls/go v0.0.0-20220914232946-0441cf4cf837
|
||||||
go.starlark.net v0.0.0-20221028183056-acb66ad56dd2
|
go.starlark.net v0.0.0-20230105143730-d7da88764354
|
||||||
golang.org/x/crypto v0.3.0
|
golang.org/x/crypto v0.5.0
|
||||||
golang.org/x/net v0.2.0
|
golang.org/x/net v0.5.0
|
||||||
golang.org/x/sync v0.1.0
|
golang.org/x/sync v0.1.0
|
||||||
golang.org/x/sys v0.2.0
|
golang.org/x/sys v0.4.0
|
||||||
google.golang.org/grpc v1.51.0
|
google.golang.org/grpc v1.51.0
|
||||||
google.golang.org/protobuf v1.28.1
|
google.golang.org/protobuf v1.28.1
|
||||||
gvisor.dev/gvisor v0.0.0-20220901235040-6ca97ef2ce1c
|
gvisor.dev/gvisor v0.0.0-20220901235040-6ca97ef2ce1c
|
||||||
@@ -39,21 +39,22 @@ require (
|
|||||||
github.com/francoispqt/gojay v1.2.13 // indirect
|
github.com/francoispqt/gojay v1.2.13 // indirect
|
||||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect
|
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect
|
||||||
github.com/google/btree v1.1.2 // indirect
|
github.com/google/btree v1.1.2 // indirect
|
||||||
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 // indirect
|
github.com/google/pprof v0.0.0-20221219190121-3cb0bae90811 // indirect
|
||||||
github.com/klauspost/compress v1.15.12 // indirect
|
github.com/klauspost/compress v1.15.14 // indirect
|
||||||
github.com/klauspost/cpuid/v2 v2.2.1 // indirect
|
github.com/klauspost/cpuid/v2 v2.2.3 // indirect
|
||||||
github.com/kr/pretty v0.3.1 // indirect
|
github.com/kr/pretty v0.3.1 // indirect
|
||||||
github.com/marten-seemann/qtls-go1-19 v0.1.1 // indirect
|
github.com/marten-seemann/qtls-go1-19 v0.1.2 // indirect
|
||||||
github.com/onsi/ginkgo/v2 v2.5.1 // indirect
|
github.com/onsi/ginkgo/v2 v2.6.1 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 // indirect
|
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 // indirect
|
||||||
go.uber.org/atomic v1.10.0 // indirect
|
go.uber.org/atomic v1.10.0 // indirect
|
||||||
golang.org/x/exp v0.0.0-20221126150942-6ab00d035af9 // indirect
|
golang.org/x/exp v0.0.0-20230105202349-8879d0199aa3 // indirect
|
||||||
golang.org/x/mod v0.7.0 // indirect
|
golang.org/x/mod v0.7.0 // indirect
|
||||||
golang.org/x/text v0.4.0 // indirect
|
golang.org/x/text v0.6.0 // indirect
|
||||||
golang.org/x/time v0.2.0 // indirect
|
golang.org/x/time v0.3.0 // indirect
|
||||||
golang.org/x/tools v0.3.0 // indirect
|
golang.org/x/tools v0.5.0 // indirect
|
||||||
google.golang.org/genproto v0.0.0-20221118155620-16455021b5e6 // indirect
|
google.golang.org/genproto v0.0.0-20230106154932-a12b697841d9 // indirect
|
||||||
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
||||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
lukechampine.com/blake3 v1.1.7 // indirect
|
lukechampine.com/blake3 v1.1.7 // indirect
|
||||||
|
86
go.sum
86
go.sum
@@ -77,8 +77,8 @@ github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+u
|
|||||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
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/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-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||||
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ=
|
github.com/google/pprof v0.0.0-20221219190121-3cb0bae90811 h1:wORs2YN3R3ona/CXYuTvLM31QlgoNKHvlCNuArCDDCU=
|
||||||
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo=
|
github.com/google/pprof v0.0.0-20221219190121-3cb0bae90811/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo=
|
||||||
github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
|
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/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/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||||
@@ -92,12 +92,17 @@ github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0
|
|||||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
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/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/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||||
github.com/klauspost/compress v1.15.12 h1:YClS/PImqYbn+UILDnqxQCZ3RehC9N318SU3kElDUEM=
|
github.com/klauspost/compress v1.15.13 h1:NFn1Wr8cfnenSJSA46lLq4wHCcBzKTSjnBIexDMMOV0=
|
||||||
github.com/klauspost/compress v1.15.12/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM=
|
github.com/klauspost/compress v1.15.13/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM=
|
||||||
|
github.com/klauspost/compress v1.15.14 h1:i7WCKDToww0wA+9qrUZ1xOjp218vfFo3nTU6UHp+gOc=
|
||||||
|
github.com/klauspost/compress v1.15.14/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM=
|
||||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||||
github.com/klauspost/cpuid/v2 v2.2.1 h1:U33DW0aiEj633gHYw3LoDNfkDiYnE5Q8M/TKJn2f2jI=
|
github.com/klauspost/cpuid/v2 v2.2.2 h1:xPMwiykqNK9VK0NYC3+jTMYv9I6Vl3YdjZgPZKG3zO0=
|
||||||
github.com/klauspost/cpuid/v2 v2.2.1/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
|
github.com/klauspost/cpuid/v2 v2.2.2/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
|
||||||
|
github.com/klauspost/cpuid/v2 v2.2.3 h1:sxCkb+qR91z4vsqw4vGGZlDgPz3G7gjaLyK3V8y70BU=
|
||||||
|
github.com/klauspost/cpuid/v2 v2.2.3/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
|
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
@@ -105,14 +110,14 @@ github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
|||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
github.com/lucas-clemente/quic-go v0.31.0 h1:MfNp3fk0wjWRajw6quMFA3ap1AVtlU+2mtwmbVogB2M=
|
github.com/lucas-clemente/quic-go v0.31.1 h1:O8Od7hfioqq0PMYHDyBkxU2aA7iZ2W9pjbrWuja2YR4=
|
||||||
github.com/lucas-clemente/quic-go v0.31.0/go.mod h1:0wFbizLgYzqHqtlyxyCaJKlE7bYgE6JQ+54TLd/Dq2g=
|
github.com/lucas-clemente/quic-go v0.31.1/go.mod h1:0wFbizLgYzqHqtlyxyCaJKlE7bYgE6JQ+54TLd/Dq2g=
|
||||||
github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
|
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/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||||
github.com/marten-seemann/qtls-go1-18 v0.1.3 h1:R4H2Ks8P6pAtUagjFty2p7BVHn3XiwDAl7TTQf5h7TI=
|
github.com/marten-seemann/qtls-go1-18 v0.1.4 h1:ogomB+lWV3Vmwiu6RTwDVTMGx+9j7SEi98e8QB35Its=
|
||||||
github.com/marten-seemann/qtls-go1-18 v0.1.3/go.mod h1:mJttiymBAByA49mhlNZZGrH5u1uXYZJ+RW28Py7f4m4=
|
github.com/marten-seemann/qtls-go1-18 v0.1.4/go.mod h1:mJttiymBAByA49mhlNZZGrH5u1uXYZJ+RW28Py7f4m4=
|
||||||
github.com/marten-seemann/qtls-go1-19 v0.1.1 h1:mnbxeq3oEyQxQXwI4ReCgW9DPoPR94sNlqWoDZnjRIE=
|
github.com/marten-seemann/qtls-go1-19 v0.1.2 h1:ZevAEqKXH0bZmoOBPiqX2h5rhQ7cbZi+X+rlq2JUbCE=
|
||||||
github.com/marten-seemann/qtls-go1-19 v0.1.1/go.mod h1:5HTDWtVudo/WFsHKRNuOhWlbdjrfs5JHrYb0wIJqGpI=
|
github.com/marten-seemann/qtls-go1-19 v0.1.2/go.mod h1:5HTDWtVudo/WFsHKRNuOhWlbdjrfs5JHrYb0wIJqGpI=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
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/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
|
||||||
github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA=
|
github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA=
|
||||||
@@ -121,9 +126,9 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ
|
|||||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
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/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/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
|
||||||
github.com/onsi/ginkgo/v2 v2.5.1 h1:auzK7OI497k6x4OvWq+TKAcpcSAlod0doAH72oIN0Jw=
|
github.com/onsi/ginkgo/v2 v2.6.1 h1:1xQPCjcqYw/J5LchOcp4/2q/jzJFjiAOc25chhnDw+Q=
|
||||||
github.com/onsi/ginkgo/v2 v2.5.1/go.mod h1:63DOGlLAH8+REH8jUGdL3YpCpu7JODesutUjdENfUAc=
|
github.com/onsi/ginkgo/v2 v2.6.1/go.mod h1:yjiuMwPokqY1XauOgju45q3sJt6VzQ/Fict1LFVcsAo=
|
||||||
github.com/onsi/gomega v1.24.0 h1:+0glovB9Jd6z3VR+ScSwQqXVTIfJcGA9UBM8yzQxhqg=
|
github.com/onsi/gomega v1.24.1 h1:KORJXNNTzJXzu4ScJWssJfJMnJ+2QJqhoQSRwNlze9E=
|
||||||
github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
|
github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
|
||||||
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
|
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/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
||||||
@@ -147,8 +152,8 @@ github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3/go.mod h1:HgjTstv
|
|||||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||||
github.com/sagernet/sing v0.1.0 h1:FGmaP2BVPYO2IyC/3R1DaQa/zr+kOKHRgWqrmOF+Gu8=
|
github.com/sagernet/sing v0.1.2 h1:rp5AqY23P0klk2IaLEI0/WJsD8FTVlv9TaI2QSL6TDA=
|
||||||
github.com/sagernet/sing v0.1.0/go.mod h1:zvgDYKI+vCAW9RyfyrKTgleI+DOa8lzHMPC7VZo3OL4=
|
github.com/sagernet/sing v0.1.2/go.mod h1:bvmen56QnVbMrWy+nr5nsbz7U5MUPuY0L0S/XfhCsTs=
|
||||||
github.com/sagernet/sing-shadowsocks v0.1.0 h1:cDmmOkA11fzVdhyCZQEeI3ozQz+59rj8+rqPb91xux4=
|
github.com/sagernet/sing-shadowsocks v0.1.0 h1:cDmmOkA11fzVdhyCZQEeI3ozQz+59rj8+rqPb91xux4=
|
||||||
github.com/sagernet/sing-shadowsocks v0.1.0/go.mod h1:O5LtOs8Ivw686FqLpO0Zu+A0ROVE15VeqEK3yDRRAms=
|
github.com/sagernet/sing-shadowsocks v0.1.0/go.mod h1:O5LtOs8Ivw686FqLpO0Zu+A0ROVE15VeqEK3yDRRAms=
|
||||||
github.com/sagernet/wireguard-go v0.0.0-20221116151939-c99467f53f2c h1:vK2wyt9aWYHHvNLWniwijBu/n4pySypiKRhN32u/JGo=
|
github.com/sagernet/wireguard-go v0.0.0-20221116151939-c99467f53f2c h1:vK2wyt9aWYHHvNLWniwijBu/n4pySypiKRhN32u/JGo=
|
||||||
@@ -199,8 +204,10 @@ github.com/xtls/go v0.0.0-20220914232946-0441cf4cf837 h1:AHhUwwFJGl27E46OpdJHplZ
|
|||||||
github.com/xtls/go v0.0.0-20220914232946-0441cf4cf837/go.mod h1:YJTRELIWrGxR1s8xcEBgxcxBfwQfMGjdvNLTjN9XFgY=
|
github.com/xtls/go v0.0.0-20220914232946-0441cf4cf837/go.mod h1:YJTRELIWrGxR1s8xcEBgxcxBfwQfMGjdvNLTjN9XFgY=
|
||||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||||
go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
|
go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
|
||||||
go.starlark.net v0.0.0-20221028183056-acb66ad56dd2 h1:5/KzhcSqd4UgY51l17r7C5g/JiE6DRw1Vq7VJfQHuMc=
|
go.starlark.net v0.0.0-20221205180719-3fd0dac74452 h1:JZtNuL6LPB+scU5yaQ6hqRlJFRiddZm2FwRt2AQqtHA=
|
||||||
go.starlark.net v0.0.0-20221028183056-acb66ad56dd2/go.mod h1:kIVgS18CjmEC3PqMd5kaJSGEifyV/CeB9x506ZJ1Vbk=
|
go.starlark.net v0.0.0-20221205180719-3fd0dac74452/go.mod h1:kIVgS18CjmEC3PqMd5kaJSGEifyV/CeB9x506ZJ1Vbk=
|
||||||
|
go.starlark.net v0.0.0-20230105143730-d7da88764354 h1:MqQRg4vlpVc7cQoQBgQGPyP3N4FAhKlMQ/y/Akv4/xM=
|
||||||
|
go.starlark.net v0.0.0-20230105143730-d7da88764354/go.mod h1:kIVgS18CjmEC3PqMd5kaJSGEifyV/CeB9x506ZJ1Vbk=
|
||||||
go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
|
go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
|
||||||
go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||||
go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=
|
go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=
|
||||||
@@ -209,11 +216,13 @@ golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnf
|
|||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
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.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.3.0 h1:a06MkbcxBrEFc0w0QIZWXrH/9cCX6KJyWbBOIwAn+7A=
|
golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE=
|
||||||
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20221126150942-6ab00d035af9 h1:yZNXmy+j/JpX19vZkVktWqAo7Gny4PBWYYK3zskGpx4=
|
golang.org/x/exp v0.0.0-20221217163422-3c43f8badb15 h1:5oN1Pz/eDhCpbMbLstvIPa0b/BEQo6g6nwV3pLjfM6w=
|
||||||
golang.org/x/exp v0.0.0-20221126150942-6ab00d035af9/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
|
golang.org/x/exp v0.0.0-20221217163422-3c43f8badb15/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
|
||||||
|
golang.org/x/exp v0.0.0-20230105202349-8879d0199aa3 h1:fJwx88sMf5RXwDwziL0/Mn9Wqs+efMSo/RYcL+37W9c=
|
||||||
|
golang.org/x/exp v0.0.0-20230105202349-8879d0199aa3/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
|
||||||
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
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-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||||
@@ -234,8 +243,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
|
|||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||||
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.2.0 h1:sZfSu1wtKLGlWI4ZZayP0ck9Y73K1ynO6gqzTdBVdPU=
|
golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw=
|
||||||
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
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-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-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
@@ -263,20 +272,20 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A=
|
golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18=
|
||||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
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.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=
|
golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k=
|
||||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
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.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.2.0 h1:52I/1L54xyEQAYdtcSuxtiT84KGYTBGXwayxmIpNJhE=
|
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
|
||||||
golang.org/x/time v0.2.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/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-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
@@ -287,8 +296,10 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn
|
|||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||||
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||||
golang.org/x/tools v0.3.0 h1:SrNbZl6ECOS1qFzgTdQfWXZM9XBkiA6tkFrH9YSTPHM=
|
golang.org/x/tools v0.4.0 h1:7mTAgkunk3fr4GAloyyCasadO6h9zSsQZbwvcaIciV4=
|
||||||
golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k=
|
golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ=
|
||||||
|
golang.org/x/tools v0.5.0 h1:+bSpV5HIeWkuvgaMfI3UmKRThoTA5ODJTUd8T17NO+4=
|
||||||
|
golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
@@ -307,8 +318,10 @@ google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk
|
|||||||
google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||||
google.golang.org/genproto v0.0.0-20221118155620-16455021b5e6 h1:a2S6M0+660BgMNl++4JPlcAO/CjkqYItDEZwkoDQK7c=
|
google.golang.org/genproto v0.0.0-20221207170731-23e4bf6bdc37 h1:jmIfw8+gSvXcZSgaFAGyInDXeWzUhvYH57G/5GKMn70=
|
||||||
google.golang.org/genproto v0.0.0-20221118155620-16455021b5e6/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg=
|
google.golang.org/genproto v0.0.0-20221207170731-23e4bf6bdc37/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=
|
||||||
|
google.golang.org/genproto v0.0.0-20230106154932-a12b697841d9 h1:3wPBShTLWQnEkZ9VW/HZZ8zT/9LLtleBtq7l8SKtJIA=
|
||||||
|
google.golang.org/genproto v0.0.0-20230106154932-a12b697841d9/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=
|
||||||
google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
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.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.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||||
@@ -330,7 +343,8 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ
|
|||||||
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
|
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
|
||||||
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
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-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
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.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.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
@@ -53,6 +53,7 @@ type HTTPRemoteConfig struct {
|
|||||||
|
|
||||||
type HTTPClientConfig struct {
|
type HTTPClientConfig struct {
|
||||||
Servers []*HTTPRemoteConfig `json:"servers"`
|
Servers []*HTTPRemoteConfig `json:"servers"`
|
||||||
|
Headers map[string]string `json:"headers"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *HTTPClientConfig) Build() (proto.Message, error) {
|
func (v *HTTPClientConfig) Build() (proto.Message, error) {
|
||||||
@@ -77,5 +78,12 @@ func (v *HTTPClientConfig) Build() (proto.Message, error) {
|
|||||||
}
|
}
|
||||||
config.Server[idx] = server
|
config.Server[idx] = server
|
||||||
}
|
}
|
||||||
|
config.Header = make([]*http.Header, 0, 32)
|
||||||
|
for key, value := range v.Headers {
|
||||||
|
config.Header = append(config.Header, &http.Header{
|
||||||
|
Key: key,
|
||||||
|
Value: value,
|
||||||
|
})
|
||||||
|
}
|
||||||
return config, nil
|
return config, nil
|
||||||
}
|
}
|
||||||
|
@@ -107,7 +107,7 @@ func buildShadowsocks2022(v *ShadowsocksServerConfig) (proto.Message, error) {
|
|||||||
config.Email = v.Email
|
config.Email = v.Email
|
||||||
return config, nil
|
return config, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if v.Cipher == "" {
|
if v.Cipher == "" {
|
||||||
return nil, newError("shadowsocks 2022 (multi-user): missing server method")
|
return nil, newError("shadowsocks 2022 (multi-user): missing server method")
|
||||||
}
|
}
|
||||||
@@ -120,7 +120,7 @@ func buildShadowsocks2022(v *ShadowsocksServerConfig) (proto.Message, error) {
|
|||||||
config.Method = v.Cipher
|
config.Method = v.Cipher
|
||||||
config.Key = v.Password
|
config.Key = v.Password
|
||||||
config.Network = v.NetworkList.Build()
|
config.Network = v.NetworkList.Build()
|
||||||
|
|
||||||
for _, user := range v.Users {
|
for _, user := range v.Users {
|
||||||
if user.Cipher != "" {
|
if user.Cipher != "" {
|
||||||
return nil, newError("shadowsocks 2022 (multi-user): users must have empty method")
|
return nil, newError("shadowsocks 2022 (multi-user): users must have empty method")
|
||||||
@@ -145,10 +145,10 @@ func buildShadowsocks2022(v *ShadowsocksServerConfig) (proto.Message, error) {
|
|||||||
return nil, newError("shadowsocks 2022 (relay): all users must have relay address")
|
return nil, newError("shadowsocks 2022 (relay): all users must have relay address")
|
||||||
}
|
}
|
||||||
config.Destinations = append(config.Destinations, &shadowsocks_2022.RelayDestination{
|
config.Destinations = append(config.Destinations, &shadowsocks_2022.RelayDestination{
|
||||||
Key: user.Password,
|
Key: user.Password,
|
||||||
Email: user.Email,
|
Email: user.Email,
|
||||||
Address: user.Address.Build(),
|
Address: user.Address.Build(),
|
||||||
Port: uint32(user.Port),
|
Port: uint32(user.Port),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return config, nil
|
return config, nil
|
||||||
|
@@ -533,7 +533,7 @@ type SocketConfig struct {
|
|||||||
DialerProxy string `json:"dialerProxy"`
|
DialerProxy string `json:"dialerProxy"`
|
||||||
TCPKeepAliveInterval int32 `json:"tcpKeepAliveInterval"`
|
TCPKeepAliveInterval int32 `json:"tcpKeepAliveInterval"`
|
||||||
TCPKeepAliveIdle int32 `json:"tcpKeepAliveIdle"`
|
TCPKeepAliveIdle int32 `json:"tcpKeepAliveIdle"`
|
||||||
TCPCongestion string `json:"tcpCongestion"`
|
TCPCongestion string `json:"tcpCongestion"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build implements Buildable.
|
// Build implements Buildable.
|
||||||
@@ -582,7 +582,7 @@ func (c *SocketConfig) Build() (*internet.SocketConfig, error) {
|
|||||||
DialerProxy: c.DialerProxy,
|
DialerProxy: c.DialerProxy,
|
||||||
TcpKeepAliveInterval: c.TCPKeepAliveInterval,
|
TcpKeepAliveInterval: c.TCPKeepAliveInterval,
|
||||||
TcpKeepAliveIdle: c.TCPKeepAliveIdle,
|
TcpKeepAliveIdle: c.TCPKeepAliveIdle,
|
||||||
TcpCongestion: c.TCPCongestion,
|
TcpCongestion: c.TCPCongestion,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -4,6 +4,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/golang/protobuf/proto"
|
"github.com/golang/protobuf/proto"
|
||||||
@@ -52,7 +53,15 @@ func (c *VLessInboundConfig) Build() (proto.Message, error) {
|
|||||||
}
|
}
|
||||||
account.Id = u.String()
|
account.Id = u.String()
|
||||||
|
|
||||||
switch account.Flow {
|
accountFlow := account.Flow
|
||||||
|
flows := strings.Split(account.Flow, ",")
|
||||||
|
for _, f := range flows {
|
||||||
|
t := strings.TrimSpace(f)
|
||||||
|
if t != "none" {
|
||||||
|
accountFlow = t
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch accountFlow {
|
||||||
case "", vless.XRO, vless.XRD, vless.XRV:
|
case "", vless.XRO, vless.XRD, vless.XRV:
|
||||||
case vless.XRS:
|
case vless.XRS:
|
||||||
return nil, newError(`VLESS clients: inbound doesn't support "xtls-rprx-splice" in this version, please use "xtls-rprx-direct" instead`)
|
return nil, newError(`VLESS clients: inbound doesn't support "xtls-rprx-splice" in this version, please use "xtls-rprx-direct" instead`)
|
||||||
|
@@ -2,12 +2,14 @@ package http
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"sync"
|
"sync"
|
||||||
|
"text/template"
|
||||||
|
|
||||||
"github.com/xtls/xray-core/common"
|
"github.com/xtls/xray-core/common"
|
||||||
"github.com/xtls/xray-core/common/buf"
|
"github.com/xtls/xray-core/common/buf"
|
||||||
@@ -30,6 +32,7 @@ import (
|
|||||||
type Client struct {
|
type Client struct {
|
||||||
serverPicker protocol.ServerPicker
|
serverPicker protocol.ServerPicker
|
||||||
policyManager policy.Manager
|
policyManager policy.Manager
|
||||||
|
header []*Header
|
||||||
}
|
}
|
||||||
|
|
||||||
type h2Conn struct {
|
type h2Conn struct {
|
||||||
@@ -60,6 +63,7 @@ func NewClient(ctx context.Context, config *ClientConfig) (*Client, error) {
|
|||||||
return &Client{
|
return &Client{
|
||||||
serverPicker: protocol.NewRoundRobinServerPicker(serverList),
|
serverPicker: protocol.NewRoundRobinServerPicker(serverList),
|
||||||
policyManager: v.GetFeature(policy.ManagerType()).(policy.Manager),
|
policyManager: v.GetFeature(policy.ManagerType()).(policy.Manager),
|
||||||
|
header: config.Header,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,12 +92,17 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter
|
|||||||
buf.ReleaseMulti(mbuf)
|
buf.ReleaseMulti(mbuf)
|
||||||
defer bytespool.Free(firstPayload)
|
defer bytespool.Free(firstPayload)
|
||||||
|
|
||||||
|
header, err := fillRequestHeader(ctx, c.header)
|
||||||
|
if err != nil {
|
||||||
|
return newError("failed to fill out header").Base(err)
|
||||||
|
}
|
||||||
|
|
||||||
if err := retry.ExponentialBackoff(5, 100).On(func() error {
|
if err := retry.ExponentialBackoff(5, 100).On(func() error {
|
||||||
server := c.serverPicker.PickServer()
|
server := c.serverPicker.PickServer()
|
||||||
dest := server.Destination()
|
dest := server.Destination()
|
||||||
user = server.PickUser()
|
user = server.PickUser()
|
||||||
|
|
||||||
netConn, err := setUpHTTPTunnel(ctx, dest, targetAddr, user, dialer, firstPayload)
|
netConn, err := setUpHTTPTunnel(ctx, dest, targetAddr, user, dialer, header, firstPayload)
|
||||||
if netConn != nil {
|
if netConn != nil {
|
||||||
if _, ok := netConn.(*http2Conn); !ok {
|
if _, ok := netConn.(*http2Conn); !ok {
|
||||||
if _, err := netConn.Write(firstPayload); err != nil {
|
if _, err := netConn.Write(firstPayload); err != nil {
|
||||||
@@ -139,8 +148,42 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fillRequestHeader will fill out the template of the headers
|
||||||
|
func fillRequestHeader(ctx context.Context, header []*Header) ([]*Header, error) {
|
||||||
|
if len(header) == 0 {
|
||||||
|
return header, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
inbound := session.InboundFromContext(ctx)
|
||||||
|
outbound := session.OutboundFromContext(ctx)
|
||||||
|
|
||||||
|
data := struct {
|
||||||
|
Source net.Destination
|
||||||
|
Target net.Destination
|
||||||
|
}{
|
||||||
|
Source: inbound.Source,
|
||||||
|
Target: outbound.Target,
|
||||||
|
}
|
||||||
|
|
||||||
|
filled := make([]*Header, len(header))
|
||||||
|
for i, h := range header {
|
||||||
|
tmpl, err := template.New(h.Key).Parse(h.Value)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var buf bytes.Buffer
|
||||||
|
|
||||||
|
if err = tmpl.Execute(&buf, data); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
filled[i] = &Header{Key: h.Key, Value: buf.String()}
|
||||||
|
}
|
||||||
|
|
||||||
|
return filled, nil
|
||||||
|
}
|
||||||
|
|
||||||
// setUpHTTPTunnel will create a socket tunnel via HTTP CONNECT method
|
// setUpHTTPTunnel will create a socket tunnel via HTTP CONNECT method
|
||||||
func setUpHTTPTunnel(ctx context.Context, dest net.Destination, target string, user *protocol.MemoryUser, dialer internet.Dialer, firstPayload []byte) (net.Conn, error) {
|
func setUpHTTPTunnel(ctx context.Context, dest net.Destination, target string, user *protocol.MemoryUser, dialer internet.Dialer, header []*Header, firstPayload []byte) (net.Conn, error) {
|
||||||
req := &http.Request{
|
req := &http.Request{
|
||||||
Method: http.MethodConnect,
|
Method: http.MethodConnect,
|
||||||
URL: &url.URL{Host: target},
|
URL: &url.URL{Host: target},
|
||||||
@@ -154,6 +197,10 @@ func setUpHTTPTunnel(ctx context.Context, dest net.Destination, target string, u
|
|||||||
req.Header.Set("Proxy-Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte(auth)))
|
req.Header.Set("Proxy-Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte(auth)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, h := range header {
|
||||||
|
req.Header.Set(h.Key, h.Value)
|
||||||
|
}
|
||||||
|
|
||||||
connectHTTP1 := func(rawConn net.Conn) (net.Conn, error) {
|
connectHTTP1 := func(rawConn net.Conn) (net.Conn, error) {
|
||||||
req.Header.Set("Proxy-Connection", "Keep-Alive")
|
req.Header.Set("Proxy-Connection", "Keep-Alive")
|
||||||
|
|
||||||
|
@@ -150,6 +150,61 @@ func (x *ServerConfig) GetUserLevel() uint32 {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Header struct {
|
||||||
|
state protoimpl.MessageState
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
|
Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
|
||||||
|
Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Header) Reset() {
|
||||||
|
*x = Header{}
|
||||||
|
if protoimpl.UnsafeEnabled {
|
||||||
|
mi := &file_proxy_http_config_proto_msgTypes[2]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Header) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*Header) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *Header) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_proxy_http_config_proto_msgTypes[2]
|
||||||
|
if protoimpl.UnsafeEnabled && x != nil {
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
return ms
|
||||||
|
}
|
||||||
|
return mi.MessageOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use Header.ProtoReflect.Descriptor instead.
|
||||||
|
func (*Header) Descriptor() ([]byte, []int) {
|
||||||
|
return file_proxy_http_config_proto_rawDescGZIP(), []int{2}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Header) GetKey() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.Key
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Header) GetValue() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.Value
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
// ClientConfig is the protobuf config for HTTP proxy client.
|
// ClientConfig is the protobuf config for HTTP proxy client.
|
||||||
type ClientConfig struct {
|
type ClientConfig struct {
|
||||||
state protoimpl.MessageState
|
state protoimpl.MessageState
|
||||||
@@ -158,12 +213,13 @@ type ClientConfig struct {
|
|||||||
|
|
||||||
// Sever is a list of HTTP server addresses.
|
// Sever is a list of HTTP server addresses.
|
||||||
Server []*protocol.ServerEndpoint `protobuf:"bytes,1,rep,name=server,proto3" json:"server,omitempty"`
|
Server []*protocol.ServerEndpoint `protobuf:"bytes,1,rep,name=server,proto3" json:"server,omitempty"`
|
||||||
|
Header []*Header `protobuf:"bytes,2,rep,name=header,proto3" json:"header,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *ClientConfig) Reset() {
|
func (x *ClientConfig) Reset() {
|
||||||
*x = ClientConfig{}
|
*x = ClientConfig{}
|
||||||
if protoimpl.UnsafeEnabled {
|
if protoimpl.UnsafeEnabled {
|
||||||
mi := &file_proxy_http_config_proto_msgTypes[2]
|
mi := &file_proxy_http_config_proto_msgTypes[3]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@@ -176,7 +232,7 @@ func (x *ClientConfig) String() string {
|
|||||||
func (*ClientConfig) ProtoMessage() {}
|
func (*ClientConfig) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *ClientConfig) ProtoReflect() protoreflect.Message {
|
func (x *ClientConfig) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_proxy_http_config_proto_msgTypes[2]
|
mi := &file_proxy_http_config_proto_msgTypes[3]
|
||||||
if protoimpl.UnsafeEnabled && x != nil {
|
if protoimpl.UnsafeEnabled && x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@@ -189,7 +245,7 @@ func (x *ClientConfig) ProtoReflect() protoreflect.Message {
|
|||||||
|
|
||||||
// Deprecated: Use ClientConfig.ProtoReflect.Descriptor instead.
|
// Deprecated: Use ClientConfig.ProtoReflect.Descriptor instead.
|
||||||
func (*ClientConfig) Descriptor() ([]byte, []int) {
|
func (*ClientConfig) Descriptor() ([]byte, []int) {
|
||||||
return file_proxy_http_config_proto_rawDescGZIP(), []int{2}
|
return file_proxy_http_config_proto_rawDescGZIP(), []int{3}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *ClientConfig) GetServer() []*protocol.ServerEndpoint {
|
func (x *ClientConfig) GetServer() []*protocol.ServerEndpoint {
|
||||||
@@ -199,6 +255,13 @@ func (x *ClientConfig) GetServer() []*protocol.ServerEndpoint {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (x *ClientConfig) GetHeader() []*Header {
|
||||||
|
if x != nil {
|
||||||
|
return x.Header
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
var File_proxy_http_config_proto protoreflect.FileDescriptor
|
var File_proxy_http_config_proto protoreflect.FileDescriptor
|
||||||
|
|
||||||
var file_proxy_http_config_proto_rawDesc = []byte{
|
var file_proxy_http_config_proto_rawDesc = []byte{
|
||||||
@@ -227,17 +290,23 @@ var file_proxy_http_config_proto_rawDesc = []byte{
|
|||||||
0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01,
|
0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01,
|
||||||
0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
|
0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
|
||||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38,
|
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38,
|
||||||
0x01, 0x22, 0x4c, 0x0a, 0x0c, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69,
|
0x01, 0x22, 0x30, 0x0a, 0x06, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x6b,
|
||||||
0x67, 0x12, 0x3c, 0x0a, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x03, 0x28,
|
0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a,
|
||||||
0x0b, 0x32, 0x24, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e,
|
0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61,
|
||||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x45,
|
0x6c, 0x75, 0x65, 0x22, 0x7d, 0x0a, 0x0c, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e,
|
||||||
0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x42,
|
0x66, 0x69, 0x67, 0x12, 0x3c, 0x0a, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20,
|
||||||
0x4f, 0x0a, 0x13, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x78,
|
0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f,
|
||||||
0x79, 0x2e, 0x68, 0x74, 0x74, 0x70, 0x50, 0x01, 0x5a, 0x24, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
|
0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65,
|
||||||
0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, 0x63,
|
0x72, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65,
|
||||||
0x6f, 0x72, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x68, 0x74, 0x74, 0x70, 0xaa, 0x02,
|
0x72, 0x12, 0x2f, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x02, 0x20, 0x03, 0x28,
|
||||||
0x0f, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x48, 0x74, 0x74, 0x70,
|
0x0b, 0x32, 0x17, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x68,
|
||||||
0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
0x74, 0x74, 0x70, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64,
|
||||||
|
0x65, 0x72, 0x42, 0x4f, 0x0a, 0x13, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x70,
|
||||||
|
0x72, 0x6f, 0x78, 0x79, 0x2e, 0x68, 0x74, 0x74, 0x70, 0x50, 0x01, 0x5a, 0x24, 0x67, 0x69, 0x74,
|
||||||
|
0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61,
|
||||||
|
0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x68, 0x74, 0x74,
|
||||||
|
0x70, 0xaa, 0x02, 0x0f, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x48,
|
||||||
|
0x74, 0x74, 0x70, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -252,22 +321,24 @@ func file_proxy_http_config_proto_rawDescGZIP() []byte {
|
|||||||
return file_proxy_http_config_proto_rawDescData
|
return file_proxy_http_config_proto_rawDescData
|
||||||
}
|
}
|
||||||
|
|
||||||
var file_proxy_http_config_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
|
var file_proxy_http_config_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
|
||||||
var file_proxy_http_config_proto_goTypes = []interface{}{
|
var file_proxy_http_config_proto_goTypes = []interface{}{
|
||||||
(*Account)(nil), // 0: xray.proxy.http.Account
|
(*Account)(nil), // 0: xray.proxy.http.Account
|
||||||
(*ServerConfig)(nil), // 1: xray.proxy.http.ServerConfig
|
(*ServerConfig)(nil), // 1: xray.proxy.http.ServerConfig
|
||||||
(*ClientConfig)(nil), // 2: xray.proxy.http.ClientConfig
|
(*Header)(nil), // 2: xray.proxy.http.Header
|
||||||
nil, // 3: xray.proxy.http.ServerConfig.AccountsEntry
|
(*ClientConfig)(nil), // 3: xray.proxy.http.ClientConfig
|
||||||
(*protocol.ServerEndpoint)(nil), // 4: xray.common.protocol.ServerEndpoint
|
nil, // 4: xray.proxy.http.ServerConfig.AccountsEntry
|
||||||
|
(*protocol.ServerEndpoint)(nil), // 5: xray.common.protocol.ServerEndpoint
|
||||||
}
|
}
|
||||||
var file_proxy_http_config_proto_depIdxs = []int32{
|
var file_proxy_http_config_proto_depIdxs = []int32{
|
||||||
3, // 0: xray.proxy.http.ServerConfig.accounts:type_name -> xray.proxy.http.ServerConfig.AccountsEntry
|
4, // 0: xray.proxy.http.ServerConfig.accounts:type_name -> xray.proxy.http.ServerConfig.AccountsEntry
|
||||||
4, // 1: xray.proxy.http.ClientConfig.server:type_name -> xray.common.protocol.ServerEndpoint
|
5, // 1: xray.proxy.http.ClientConfig.server:type_name -> xray.common.protocol.ServerEndpoint
|
||||||
2, // [2:2] is the sub-list for method output_type
|
2, // 2: xray.proxy.http.ClientConfig.header:type_name -> xray.proxy.http.Header
|
||||||
2, // [2:2] is the sub-list for method input_type
|
3, // [3:3] is the sub-list for method output_type
|
||||||
2, // [2:2] is the sub-list for extension type_name
|
3, // [3:3] is the sub-list for method input_type
|
||||||
2, // [2:2] is the sub-list for extension extendee
|
3, // [3:3] is the sub-list for extension type_name
|
||||||
0, // [0:2] is the sub-list for field type_name
|
3, // [3:3] is the sub-list for extension extendee
|
||||||
|
0, // [0:3] is the sub-list for field type_name
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() { file_proxy_http_config_proto_init() }
|
func init() { file_proxy_http_config_proto_init() }
|
||||||
@@ -301,6 +372,18 @@ func file_proxy_http_config_proto_init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
file_proxy_http_config_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
file_proxy_http_config_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||||
|
switch v := v.(*Header); i {
|
||||||
|
case 0:
|
||||||
|
return &v.state
|
||||||
|
case 1:
|
||||||
|
return &v.sizeCache
|
||||||
|
case 2:
|
||||||
|
return &v.unknownFields
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file_proxy_http_config_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
||||||
switch v := v.(*ClientConfig); i {
|
switch v := v.(*ClientConfig); i {
|
||||||
case 0:
|
case 0:
|
||||||
return &v.state
|
return &v.state
|
||||||
@@ -319,7 +402,7 @@ func file_proxy_http_config_proto_init() {
|
|||||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||||
RawDescriptor: file_proxy_http_config_proto_rawDesc,
|
RawDescriptor: file_proxy_http_config_proto_rawDesc,
|
||||||
NumEnums: 0,
|
NumEnums: 0,
|
||||||
NumMessages: 4,
|
NumMessages: 5,
|
||||||
NumExtensions: 0,
|
NumExtensions: 0,
|
||||||
NumServices: 0,
|
NumServices: 0,
|
||||||
},
|
},
|
||||||
|
@@ -21,8 +21,14 @@ message ServerConfig {
|
|||||||
uint32 user_level = 4;
|
uint32 user_level = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message Header {
|
||||||
|
string key = 1;
|
||||||
|
string value = 2;
|
||||||
|
}
|
||||||
|
|
||||||
// ClientConfig is the protobuf config for HTTP proxy client.
|
// ClientConfig is the protobuf config for HTTP proxy client.
|
||||||
message ClientConfig {
|
message ClientConfig {
|
||||||
// Sever is a list of HTTP server addresses.
|
// Sever is a list of HTTP server addresses.
|
||||||
repeated xray.common.protocol.ServerEndpoint server = 1;
|
repeated xray.common.protocol.ServerEndpoint server = 1;
|
||||||
|
repeated Header header = 2;
|
||||||
}
|
}
|
||||||
|
29
proxy/shadowsocks_2022/config.go
Normal file
29
proxy/shadowsocks_2022/config.go
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
package shadowsocks_2022
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/xtls/xray-core/common/protocol"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MemoryAccount is an account type converted from Account.
|
||||||
|
type MemoryAccount struct {
|
||||||
|
Key string
|
||||||
|
Email string
|
||||||
|
Level int32
|
||||||
|
}
|
||||||
|
|
||||||
|
// AsAccount implements protocol.AsAccount.
|
||||||
|
func (u *User) AsAccount() (protocol.Account, error) {
|
||||||
|
return &MemoryAccount{
|
||||||
|
Key: u.GetKey(),
|
||||||
|
Email: u.GetEmail(),
|
||||||
|
Level: u.GetLevel(),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Equals implements protocol.Account.Equals().
|
||||||
|
func (a *MemoryAccount) Equals(another protocol.Account) bool {
|
||||||
|
if account, ok := another.(*MemoryAccount); ok {
|
||||||
|
return a.Key == account.Key
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
@@ -4,6 +4,8 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/sagernet/sing-shadowsocks/shadowaead_2022"
|
"github.com/sagernet/sing-shadowsocks/shadowaead_2022"
|
||||||
C "github.com/sagernet/sing/common"
|
C "github.com/sagernet/sing/common"
|
||||||
@@ -31,6 +33,7 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type MultiUserInbound struct {
|
type MultiUserInbound struct {
|
||||||
|
sync.Mutex
|
||||||
networks []net.Network
|
networks []net.Network
|
||||||
users []*User
|
users []*User
|
||||||
service *shadowaead_2022.MultiService[int]
|
service *shadowaead_2022.MultiService[int]
|
||||||
@@ -78,6 +81,72 @@ func NewMultiServer(ctx context.Context, config *MultiUserServerConfig) (*MultiU
|
|||||||
return inbound, nil
|
return inbound, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddUser implements proxy.UserManager.AddUser().
|
||||||
|
func (i *MultiUserInbound) AddUser(ctx context.Context, u *protocol.MemoryUser) error {
|
||||||
|
i.Lock()
|
||||||
|
defer i.Unlock()
|
||||||
|
|
||||||
|
account := u.Account.(*MemoryAccount)
|
||||||
|
if account.Email != "" {
|
||||||
|
for idx := range i.users {
|
||||||
|
if i.users[idx].Email == account.Email {
|
||||||
|
return newError("User ", account.Email, " already exists.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i.users = append(i.users, &User{
|
||||||
|
Key: account.Key,
|
||||||
|
Email: account.Email,
|
||||||
|
Level: account.Level,
|
||||||
|
})
|
||||||
|
|
||||||
|
// sync to multi service
|
||||||
|
// Considering implements shadowsocks2022 in xray-core may have better performance.
|
||||||
|
i.service.UpdateUsersWithPasswords(
|
||||||
|
C.MapIndexed(i.users, func(index int, it *User) int { return index }),
|
||||||
|
C.Map(i.users, func(it *User) string { return it.Key }),
|
||||||
|
)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveUser implements proxy.UserManager.RemoveUser().
|
||||||
|
func (i *MultiUserInbound) RemoveUser(ctx context.Context, email string) error {
|
||||||
|
if email == "" {
|
||||||
|
return newError("Email must not be empty.")
|
||||||
|
}
|
||||||
|
|
||||||
|
i.Lock()
|
||||||
|
defer i.Unlock()
|
||||||
|
|
||||||
|
idx := -1
|
||||||
|
for ii, u := range i.users {
|
||||||
|
if strings.EqualFold(u.Email, email) {
|
||||||
|
idx = ii
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if idx == -1 {
|
||||||
|
return newError("User ", email, " not found.")
|
||||||
|
}
|
||||||
|
|
||||||
|
ulen := len(i.users)
|
||||||
|
|
||||||
|
i.users[idx] = i.users[ulen-1]
|
||||||
|
i.users[ulen-1] = nil
|
||||||
|
i.users = i.users[:ulen-1]
|
||||||
|
|
||||||
|
// sync to multi service
|
||||||
|
// Considering implements shadowsocks2022 in xray-core may have better performance.
|
||||||
|
i.service.UpdateUsersWithPasswords(
|
||||||
|
C.MapIndexed(i.users, func(index int, it *User) int { return index }),
|
||||||
|
C.Map(i.users, func(it *User) string { return it.Key }),
|
||||||
|
)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (i *MultiUserInbound) Network() []net.Network {
|
func (i *MultiUserInbound) Network() []net.Network {
|
||||||
return i.networks
|
return i.networks
|
||||||
}
|
}
|
||||||
|
@@ -31,10 +31,12 @@ const (
|
|||||||
Version = byte(0)
|
Version = byte(0)
|
||||||
)
|
)
|
||||||
|
|
||||||
var tls13SupportedVersions = []byte{0x00, 0x2b, 0x00, 0x02, 0x03, 0x04}
|
var (
|
||||||
var tlsClientHandShakeStart = []byte{0x16, 0x03}
|
tls13SupportedVersions = []byte{0x00, 0x2b, 0x00, 0x02, 0x03, 0x04}
|
||||||
var tlsServerHandShakeStart = []byte{0x16, 0x03, 0x03}
|
tlsClientHandShakeStart = []byte{0x16, 0x03}
|
||||||
var tlsApplicationDataStart = []byte{0x17, 0x03, 0x03}
|
tlsServerHandShakeStart = []byte{0x16, 0x03, 0x03}
|
||||||
|
tlsApplicationDataStart = []byte{0x17, 0x03, 0x03}
|
||||||
|
)
|
||||||
|
|
||||||
var addrParser = protocol.NewAddressParser(
|
var addrParser = protocol.NewAddressParser(
|
||||||
protocol.AddressFamilyByte(byte(protocol.AddressTypeIPv4), net.AddressFamilyIPv4),
|
protocol.AddressFamilyByte(byte(protocol.AddressTypeIPv4), net.AddressFamilyIPv4),
|
||||||
@@ -247,9 +249,11 @@ func ReadV(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater, c
|
|||||||
}
|
}
|
||||||
|
|
||||||
// XtlsRead filter and read xtls protocol
|
// XtlsRead filter and read xtls protocol
|
||||||
func XtlsRead(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater, conn net.Conn, rawConn syscall.RawConn,
|
func XtlsRead(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater, conn net.Conn, rawConn syscall.RawConn,
|
||||||
counter stats.Counter, ctx context.Context, userUUID []byte, numberOfPacketToFilter *int, enableXtls *bool,
|
input *bytes.Reader, rawInput *bytes.Buffer,
|
||||||
isTLS12orAbove *bool, isTLS *bool, cipher *uint16, remainingServerHello *int32) error {
|
counter stats.Counter, ctx context.Context, userUUID []byte, numberOfPacketToFilter *int, enableXtls *bool,
|
||||||
|
isTLS12orAbove *bool, isTLS *bool, cipher *uint16, remainingServerHello *int32,
|
||||||
|
) error {
|
||||||
err := func() error {
|
err := func() error {
|
||||||
var ct stats.Counter
|
var ct stats.Counter
|
||||||
filterUUID := true
|
filterUUID := true
|
||||||
@@ -260,8 +264,8 @@ func XtlsRead(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater
|
|||||||
for {
|
for {
|
||||||
if shouldSwitchToDirectCopy {
|
if shouldSwitchToDirectCopy {
|
||||||
shouldSwitchToDirectCopy = false
|
shouldSwitchToDirectCopy = false
|
||||||
if runtime.GOOS == "linux" || runtime.GOOS == "android" {
|
if inbound := session.InboundFromContext(ctx); inbound != nil && inbound.Conn != nil && (runtime.GOOS == "linux" || runtime.GOOS == "android") {
|
||||||
if inbound := session.InboundFromContext(ctx); inbound != nil && inbound.Conn != nil {
|
if _, ok := inbound.User.Account.(*vless.MemoryAccount); inbound.User.Account == nil || ok {
|
||||||
iConn := inbound.Conn
|
iConn := inbound.Conn
|
||||||
statConn, ok := iConn.(*stat.CounterConnection)
|
statConn, ok := iConn.(*stat.CounterConnection)
|
||||||
if ok {
|
if ok {
|
||||||
@@ -281,11 +285,7 @@ func XtlsRead(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater
|
|||||||
statConn.WriteCounter.Add(w)
|
statConn.WriteCounter.Add(w)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
} else {
|
|
||||||
panic("XTLS Splice: not TCP inbound")
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// panic("XTLS Splice: nil inbound or nil inbound.Conn")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
reader = buf.NewReadVReader(conn, rawConn, nil)
|
reader = buf.NewReadVReader(conn, rawConn, nil)
|
||||||
@@ -302,6 +302,17 @@ func XtlsRead(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater
|
|||||||
} else if currentCommand == 2 {
|
} else if currentCommand == 2 {
|
||||||
filterUUID = false
|
filterUUID = false
|
||||||
shouldSwitchToDirectCopy = true
|
shouldSwitchToDirectCopy = true
|
||||||
|
// XTLS Vision processes struct TLS Conn's input and rawInput
|
||||||
|
if inputBuffer, err := buf.ReadFrom(input); err == nil {
|
||||||
|
if !inputBuffer.IsEmpty() {
|
||||||
|
buffer, _ = buf.MergeMulti(buffer, inputBuffer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if rawInputBuffer, err := buf.ReadFrom(rawInput); err == nil {
|
||||||
|
if !rawInputBuffer.IsEmpty() {
|
||||||
|
buffer, _ = buf.MergeMulti(buffer, rawInputBuffer)
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if currentCommand != 0 {
|
} else if currentCommand != 0 {
|
||||||
newError("XtlsRead unknown command ", currentCommand, buffer.Len()).WriteToLog(session.ExportIDToError(ctx))
|
newError("XtlsRead unknown command ", currentCommand, buffer.Len()).WriteToLog(session.ExportIDToError(ctx))
|
||||||
}
|
}
|
||||||
@@ -330,9 +341,10 @@ func XtlsRead(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater
|
|||||||
}
|
}
|
||||||
|
|
||||||
// XtlsWrite filter and write xtls protocol
|
// XtlsWrite filter and write xtls protocol
|
||||||
func XtlsWrite(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater, conn net.Conn, counter stats.Counter,
|
func XtlsWrite(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater, conn net.Conn, counter stats.Counter,
|
||||||
ctx context.Context, userUUID *[]byte, numberOfPacketToFilter *int, enableXtls *bool, isTLS12orAbove *bool, isTLS *bool,
|
ctx context.Context, userUUID *[]byte, numberOfPacketToFilter *int, enableXtls *bool, isTLS12orAbove *bool, isTLS *bool,
|
||||||
cipher *uint16, remainingServerHello *int32) error {
|
cipher *uint16, remainingServerHello *int32,
|
||||||
|
) error {
|
||||||
err := func() error {
|
err := func() error {
|
||||||
var ct stats.Counter
|
var ct stats.Counter
|
||||||
filterTlsApplicationData := true
|
filterTlsApplicationData := true
|
||||||
@@ -358,7 +370,7 @@ func XtlsWrite(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdate
|
|||||||
buffer[i] = XtlsPadding(b, command, userUUID, ctx)
|
buffer[i] = XtlsPadding(b, command, userUUID, ctx)
|
||||||
break
|
break
|
||||||
} else if !*isTLS12orAbove && *numberOfPacketToFilter <= 0 {
|
} else if !*isTLS12orAbove && *numberOfPacketToFilter <= 0 {
|
||||||
//maybe tls 1.1 or 1.0
|
// maybe tls 1.1 or 1.0
|
||||||
filterTlsApplicationData = false
|
filterTlsApplicationData = false
|
||||||
buffer[i] = XtlsPadding(b, 0x01, userUUID, ctx)
|
buffer[i] = XtlsPadding(b, 0x01, userUUID, ctx)
|
||||||
break
|
break
|
||||||
@@ -403,8 +415,9 @@ func XtlsWrite(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdate
|
|||||||
}
|
}
|
||||||
|
|
||||||
// XtlsFilterTls filter and recognize tls 1.3 and other info
|
// XtlsFilterTls filter and recognize tls 1.3 and other info
|
||||||
func XtlsFilterTls(buffer buf.MultiBuffer, numberOfPacketToFilter *int, enableXtls *bool, isTLS12orAbove *bool, isTLS *bool,
|
func XtlsFilterTls(buffer buf.MultiBuffer, numberOfPacketToFilter *int, enableXtls *bool, isTLS12orAbove *bool, isTLS *bool,
|
||||||
cipher *uint16, remainingServerHello *int32, ctx context.Context) {
|
cipher *uint16, remainingServerHello *int32, ctx context.Context,
|
||||||
|
) {
|
||||||
for _, b := range buffer {
|
for _, b := range buffer {
|
||||||
*numberOfPacketToFilter--
|
*numberOfPacketToFilter--
|
||||||
if b.Len() >= 6 {
|
if b.Len() >= 6 {
|
||||||
@@ -415,8 +428,8 @@ func XtlsFilterTls(buffer buf.MultiBuffer, numberOfPacketToFilter *int, enableXt
|
|||||||
*isTLS = true
|
*isTLS = true
|
||||||
if b.Len() >= 79 && *remainingServerHello >= 79 {
|
if b.Len() >= 79 && *remainingServerHello >= 79 {
|
||||||
sessionIdLen := int32(b.Byte(43))
|
sessionIdLen := int32(b.Byte(43))
|
||||||
cipherSuite := b.BytesRange(43 + sessionIdLen + 1, 43 + sessionIdLen + 3)
|
cipherSuite := b.BytesRange(43+sessionIdLen+1, 43+sessionIdLen+3)
|
||||||
*cipher = uint16(cipherSuite[0]) << 8 | uint16(cipherSuite[1])
|
*cipher = uint16(cipherSuite[0])<<8 | uint16(cipherSuite[1])
|
||||||
} else {
|
} else {
|
||||||
newError("XtlsFilterTls short server hello, tls 1.2 or older? ", b.Len(), " ", *remainingServerHello).WriteToLog(session.ExportIDToError(ctx))
|
newError("XtlsFilterTls short server hello, tls 1.2 or older? ", b.Len(), " ", *remainingServerHello).WriteToLog(session.ExportIDToError(ctx))
|
||||||
}
|
}
|
||||||
@@ -435,7 +448,7 @@ func XtlsFilterTls(buffer buf.MultiBuffer, numberOfPacketToFilter *int, enableXt
|
|||||||
v, ok := Tls13CipherSuiteDic[*cipher]
|
v, ok := Tls13CipherSuiteDic[*cipher]
|
||||||
if !ok {
|
if !ok {
|
||||||
v = "Old cipher: " + strconv.FormatUint(uint64(*cipher), 16)
|
v = "Old cipher: " + strconv.FormatUint(uint64(*cipher), 16)
|
||||||
} else if (v != "TLS_AES_128_CCM_8_SHA256") {
|
} else if v != "TLS_AES_128_CCM_8_SHA256" {
|
||||||
*enableXtls = true
|
*enableXtls = true
|
||||||
}
|
}
|
||||||
newError("XtlsFilterTls found tls 1.3! ", b.Len(), " ", v).WriteToLog(session.ExportIDToError(ctx))
|
newError("XtlsFilterTls found tls 1.3! ", b.Len(), " ", v).WriteToLog(session.ExportIDToError(ctx))
|
||||||
@@ -446,7 +459,7 @@ func XtlsFilterTls(buffer buf.MultiBuffer, numberOfPacketToFilter *int, enableXt
|
|||||||
*numberOfPacketToFilter = 0
|
*numberOfPacketToFilter = 0
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
newError("XtlsFilterTls inclusive server hello ", b.Len(), " ", *remainingServerHello).WriteToLog(session.ExportIDToError(ctx))
|
newError("XtlsFilterTls inconclusive server hello ", b.Len(), " ", *remainingServerHello).WriteToLog(session.ExportIDToError(ctx))
|
||||||
}
|
}
|
||||||
if *numberOfPacketToFilter <= 0 {
|
if *numberOfPacketToFilter <= 0 {
|
||||||
newError("XtlsFilterTls stop filtering", buffer.Len()).WriteToLog(session.ExportIDToError(ctx))
|
newError("XtlsFilterTls stop filtering", buffer.Len()).WriteToLog(session.ExportIDToError(ctx))
|
||||||
@@ -586,9 +599,9 @@ func XtlsUnpadding(ctx context.Context, buffer buf.MultiBuffer, userUUID []byte,
|
|||||||
}
|
}
|
||||||
|
|
||||||
var Tls13CipherSuiteDic = map[uint16]string{
|
var Tls13CipherSuiteDic = map[uint16]string{
|
||||||
0x1301 : "TLS_AES_128_GCM_SHA256",
|
0x1301: "TLS_AES_128_GCM_SHA256",
|
||||||
0x1302 : "TLS_AES_256_GCM_SHA384",
|
0x1302: "TLS_AES_256_GCM_SHA384",
|
||||||
0x1303 : "TLS_CHACHA20_POLY1305_SHA256",
|
0x1303: "TLS_CHACHA20_POLY1305_SHA256",
|
||||||
0x1304 : "TLS_AES_128_CCM_SHA256",
|
0x1304: "TLS_AES_128_CCM_SHA256",
|
||||||
0x1305 : "TLS_AES_128_CCM_8_SHA256",
|
0x1305: "TLS_AES_128_CCM_8_SHA256",
|
||||||
}
|
}
|
||||||
|
@@ -3,13 +3,17 @@ package inbound
|
|||||||
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
|
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"io"
|
"io"
|
||||||
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/pires/go-proxyproto"
|
||||||
"github.com/xtls/xray-core/common"
|
"github.com/xtls/xray-core/common"
|
||||||
"github.com/xtls/xray-core/common/buf"
|
"github.com/xtls/xray-core/common/buf"
|
||||||
"github.com/xtls/xray-core/common/errors"
|
"github.com/xtls/xray-core/common/errors"
|
||||||
@@ -441,10 +445,22 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s
|
|||||||
|
|
||||||
var netConn net.Conn
|
var netConn net.Conn
|
||||||
var rawConn syscall.RawConn
|
var rawConn syscall.RawConn
|
||||||
|
var input *bytes.Reader
|
||||||
|
var rawInput *bytes.Buffer
|
||||||
|
allowNoneFlow := false
|
||||||
|
accountFlow := account.Flow
|
||||||
|
flows := strings.Split(account.Flow, ",")
|
||||||
|
for _, f := range flows {
|
||||||
|
t := strings.TrimSpace(f)
|
||||||
|
if t == "none" {
|
||||||
|
allowNoneFlow = true
|
||||||
|
} else {
|
||||||
|
accountFlow = t
|
||||||
|
}
|
||||||
|
}
|
||||||
switch requestAddons.Flow {
|
switch requestAddons.Flow {
|
||||||
case vless.XRO, vless.XRD, vless.XRV:
|
case vless.XRO, vless.XRD, vless.XRV:
|
||||||
if account.Flow == requestAddons.Flow {
|
if accountFlow == requestAddons.Flow {
|
||||||
switch request.Command {
|
switch request.Command {
|
||||||
case protocol.RequestCommandMux:
|
case protocol.RequestCommandMux:
|
||||||
return newError(requestAddons.Flow + " doesn't support Mux").AtWarning()
|
return newError(requestAddons.Flow + " doesn't support Mux").AtWarning()
|
||||||
@@ -452,11 +468,19 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s
|
|||||||
return newError(requestAddons.Flow + " doesn't support UDP").AtWarning()
|
return newError(requestAddons.Flow + " doesn't support UDP").AtWarning()
|
||||||
case protocol.RequestCommandTCP:
|
case protocol.RequestCommandTCP:
|
||||||
if requestAddons.Flow == vless.XRV {
|
if requestAddons.Flow == vless.XRV {
|
||||||
|
var t reflect.Type
|
||||||
|
var p uintptr
|
||||||
if tlsConn, ok := iConn.(*tls.Conn); ok {
|
if tlsConn, ok := iConn.(*tls.Conn); ok {
|
||||||
netConn = tlsConn.NetConn()
|
netConn = tlsConn.NetConn()
|
||||||
|
if pc, ok := netConn.(*proxyproto.Conn); ok {
|
||||||
|
netConn = pc.Raw()
|
||||||
|
// 8192 > 4096, there is no need to process pc's bufReader
|
||||||
|
}
|
||||||
if sc, ok := netConn.(syscall.Conn); ok {
|
if sc, ok := netConn.(syscall.Conn); ok {
|
||||||
rawConn, _ = sc.SyscallConn()
|
rawConn, _ = sc.SyscallConn()
|
||||||
}
|
}
|
||||||
|
t = reflect.TypeOf(tlsConn.Conn).Elem()
|
||||||
|
p = uintptr(unsafe.Pointer(tlsConn.Conn))
|
||||||
} else if _, ok := iConn.(*tls.UConn); ok {
|
} else if _, ok := iConn.(*tls.UConn); ok {
|
||||||
return newError("XTLS only supports UTLS fingerprint for the outbound.").AtWarning()
|
return newError("XTLS only supports UTLS fingerprint for the outbound.").AtWarning()
|
||||||
} else if _, ok := iConn.(*xtls.Conn); ok {
|
} else if _, ok := iConn.(*xtls.Conn); ok {
|
||||||
@@ -464,6 +488,10 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s
|
|||||||
} else {
|
} else {
|
||||||
return newError("XTLS only supports TCP, mKCP and DomainSocket for now.").AtWarning()
|
return newError("XTLS only supports TCP, mKCP and DomainSocket for now.").AtWarning()
|
||||||
}
|
}
|
||||||
|
i, _ := t.FieldByName("input")
|
||||||
|
r, _ := t.FieldByName("rawInput")
|
||||||
|
input = (*bytes.Reader)(unsafe.Pointer(p + i.Offset))
|
||||||
|
rawInput = (*bytes.Buffer)(unsafe.Pointer(p + r.Offset))
|
||||||
} else if xtlsConn, ok := iConn.(*xtls.Conn); ok {
|
} else if xtlsConn, ok := iConn.(*xtls.Conn); ok {
|
||||||
xtlsConn.RPRX = true
|
xtlsConn.RPRX = true
|
||||||
xtlsConn.SHOW = xtls_show
|
xtlsConn.SHOW = xtls_show
|
||||||
@@ -481,7 +509,11 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s
|
|||||||
} else {
|
} else {
|
||||||
return newError(account.ID.String() + " is not able to use " + requestAddons.Flow).AtWarning()
|
return newError(account.ID.String() + " is not able to use " + requestAddons.Flow).AtWarning()
|
||||||
}
|
}
|
||||||
case "":
|
case "", "none":
|
||||||
|
if accountFlow == vless.XRV && !allowNoneFlow && request.Command == protocol.RequestCommandTCP {
|
||||||
|
return newError(account.ID.String() + " is not able to use " + vless.XRV +
|
||||||
|
". Note the pure tls proxy has certain tls in tls characters. Append \",none\" in flow to suppress").AtWarning()
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return newError("unknown request flow " + requestAddons.Flow).AtWarning()
|
return newError("unknown request flow " + requestAddons.Flow).AtWarning()
|
||||||
}
|
}
|
||||||
@@ -528,11 +560,11 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s
|
|||||||
if statConn != nil {
|
if statConn != nil {
|
||||||
counter = statConn.ReadCounter
|
counter = statConn.ReadCounter
|
||||||
}
|
}
|
||||||
//TODO enable splice
|
// TODO enable splice
|
||||||
ctx = session.ContextWithInbound(ctx, nil)
|
ctx = session.ContextWithInbound(ctx, nil)
|
||||||
if requestAddons.Flow == vless.XRV {
|
if requestAddons.Flow == vless.XRV {
|
||||||
err = encoding.XtlsRead(clientReader, serverWriter, timer, netConn, rawConn, counter, ctx, account.ID.Bytes(),
|
err = encoding.XtlsRead(clientReader, serverWriter, timer, netConn, rawConn, input, rawInput, counter, ctx, account.ID.Bytes(),
|
||||||
&numberOfPacketToFilter, &enableXtls, &isTLS12orAbove, &isTLS, &cipher, &remainingServerHello)
|
&numberOfPacketToFilter, &enableXtls, &isTLS12orAbove, &isTLS, &cipher, &remainingServerHello)
|
||||||
} else {
|
} else {
|
||||||
err = encoding.ReadV(clientReader, serverWriter, timer, iConn.(*xtls.Conn), rawConn, counter, ctx)
|
err = encoding.ReadV(clientReader, serverWriter, timer, iConn.(*xtls.Conn), rawConn, counter, ctx)
|
||||||
}
|
}
|
||||||
@@ -586,7 +618,7 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s
|
|||||||
if statConn != nil {
|
if statConn != nil {
|
||||||
counter = statConn.WriteCounter
|
counter = statConn.WriteCounter
|
||||||
}
|
}
|
||||||
err = encoding.XtlsWrite(serverReader, clientWriter, timer, netConn, counter, ctx, &userUUID, &numberOfPacketToFilter,
|
err = encoding.XtlsWrite(serverReader, clientWriter, timer, netConn, counter, ctx, &userUUID, &numberOfPacketToFilter,
|
||||||
&enableXtls, &isTLS12orAbove, &isTLS, &cipher, &remainingServerHello)
|
&enableXtls, &isTLS12orAbove, &isTLS, &cipher, &remainingServerHello)
|
||||||
} else {
|
} else {
|
||||||
// from serverReader.ReadMultiBuffer to clientWriter.WriteMultiBufer
|
// from serverReader.ReadMultiBuffer to clientWriter.WriteMultiBufer
|
||||||
|
@@ -3,8 +3,12 @@ package outbound
|
|||||||
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
|
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
"reflect"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
"time"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
"github.com/xtls/xray-core/common"
|
"github.com/xtls/xray-core/common"
|
||||||
"github.com/xtls/xray-core/common/buf"
|
"github.com/xtls/xray-core/common/buf"
|
||||||
@@ -129,6 +133,8 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
|
|||||||
|
|
||||||
var netConn net.Conn
|
var netConn net.Conn
|
||||||
var rawConn syscall.RawConn
|
var rawConn syscall.RawConn
|
||||||
|
var input *bytes.Reader
|
||||||
|
var rawInput *bytes.Buffer
|
||||||
allowUDP443 := false
|
allowUDP443 := false
|
||||||
switch requestAddons.Flow {
|
switch requestAddons.Flow {
|
||||||
case vless.XRO + "-udp443", vless.XRD + "-udp443", vless.XRS + "-udp443", vless.XRV + "-udp443":
|
case vless.XRO + "-udp443", vless.XRD + "-udp443", vless.XRS + "-udp443", vless.XRV + "-udp443":
|
||||||
@@ -146,21 +152,31 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
|
|||||||
requestAddons.Flow = ""
|
requestAddons.Flow = ""
|
||||||
case protocol.RequestCommandTCP:
|
case protocol.RequestCommandTCP:
|
||||||
if requestAddons.Flow == vless.XRV {
|
if requestAddons.Flow == vless.XRV {
|
||||||
|
var t reflect.Type
|
||||||
|
var p uintptr
|
||||||
if tlsConn, ok := iConn.(*tls.Conn); ok {
|
if tlsConn, ok := iConn.(*tls.Conn); ok {
|
||||||
netConn = tlsConn.NetConn()
|
netConn = tlsConn.NetConn()
|
||||||
if sc, ok := netConn.(syscall.Conn); ok {
|
if sc, ok := netConn.(syscall.Conn); ok {
|
||||||
rawConn, _ = sc.SyscallConn()
|
rawConn, _ = sc.SyscallConn()
|
||||||
}
|
}
|
||||||
|
t = reflect.TypeOf(tlsConn.Conn).Elem()
|
||||||
|
p = uintptr(unsafe.Pointer(tlsConn.Conn))
|
||||||
} else if utlsConn, ok := iConn.(*tls.UConn); ok {
|
} else if utlsConn, ok := iConn.(*tls.UConn); ok {
|
||||||
netConn = utlsConn.Conn.NetConn()
|
netConn = utlsConn.Conn.NetConn()
|
||||||
if sc, ok := netConn.(syscall.Conn); ok {
|
if sc, ok := netConn.(syscall.Conn); ok {
|
||||||
rawConn, _ = sc.SyscallConn()
|
rawConn, _ = sc.SyscallConn()
|
||||||
}
|
}
|
||||||
|
t = reflect.TypeOf(utlsConn.Conn).Elem()
|
||||||
|
p = uintptr(unsafe.Pointer(utlsConn.Conn))
|
||||||
} else if _, ok := iConn.(*xtls.Conn); ok {
|
} else if _, ok := iConn.(*xtls.Conn); ok {
|
||||||
return newError(`failed to use ` + requestAddons.Flow + `, vision "security" must be "tls"`).AtWarning()
|
return newError(`failed to use ` + requestAddons.Flow + `, vision "security" must be "tls"`).AtWarning()
|
||||||
} else {
|
} else {
|
||||||
return newError("XTLS only supports TCP, mKCP and DomainSocket for now.").AtWarning()
|
return newError("XTLS only supports TCP, mKCP and DomainSocket for now.").AtWarning()
|
||||||
}
|
}
|
||||||
|
i, _ := t.FieldByName("input")
|
||||||
|
r, _ := t.FieldByName("rawInput")
|
||||||
|
input = (*bytes.Reader)(unsafe.Pointer(p + i.Offset))
|
||||||
|
rawInput = (*bytes.Buffer)(unsafe.Pointer(p + r.Offset))
|
||||||
} else if xtlsConn, ok := iConn.(*xtls.Conn); ok {
|
} else if xtlsConn, ok := iConn.(*xtls.Conn); ok {
|
||||||
xtlsConn.RPRX = true
|
xtlsConn.RPRX = true
|
||||||
xtlsConn.SHOW = xtls_show
|
xtlsConn.SHOW = xtls_show
|
||||||
@@ -217,20 +233,26 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
|
|||||||
serverWriter = xudp.NewPacketWriter(serverWriter, target)
|
serverWriter = xudp.NewPacketWriter(serverWriter, target)
|
||||||
}
|
}
|
||||||
userUUID := account.ID.Bytes()
|
userUUID := account.ID.Bytes()
|
||||||
multiBuffer, err1 := clientReader.ReadMultiBuffer()
|
timeoutReader, ok := clientReader.(buf.TimeoutReader)
|
||||||
if err1 != nil {
|
if ok {
|
||||||
return err1 // ...
|
multiBuffer, err1 := timeoutReader.ReadMultiBufferTimeout(time.Millisecond * 500)
|
||||||
}
|
if err1 == nil {
|
||||||
if requestAddons.Flow == vless.XRV {
|
if requestAddons.Flow == vless.XRV {
|
||||||
encoding.XtlsFilterTls(multiBuffer, &numberOfPacketToFilter, &enableXtls, &isTLS12orAbove, &isTLS, &cipher, &remainingServerHello, ctx)
|
encoding.XtlsFilterTls(multiBuffer, &numberOfPacketToFilter, &enableXtls, &isTLS12orAbove, &isTLS, &cipher, &remainingServerHello, ctx)
|
||||||
if isTLS {
|
if isTLS {
|
||||||
for i, b := range multiBuffer {
|
for i, b := range multiBuffer {
|
||||||
multiBuffer[i] = encoding.XtlsPadding(b, 0x00, &userUUID, ctx)
|
multiBuffer[i] = encoding.XtlsPadding(b, 0x00, &userUUID, ctx)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if err := serverWriter.WriteMultiBuffer(multiBuffer); err != nil {
|
||||||
|
return err // ...
|
||||||
|
}
|
||||||
|
} else if err1 != buf.ErrReadTimeout {
|
||||||
|
return err1
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
if err := serverWriter.WriteMultiBuffer(multiBuffer); err != nil {
|
newError("Reader is not timeout reader, will send out vless header separately from first payload").AtDebug().WriteToLog(session.ExportIDToError(ctx))
|
||||||
return err // ...
|
|
||||||
}
|
}
|
||||||
// Flush; bufferWriter.WriteMultiBufer now is bufferWriter.writer.WriteMultiBuffer
|
// Flush; bufferWriter.WriteMultiBufer now is bufferWriter.writer.WriteMultiBuffer
|
||||||
if err := bufferWriter.SetBuffered(false); err != nil {
|
if err := bufferWriter.SetBuffered(false); err != nil {
|
||||||
@@ -243,7 +265,7 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
|
|||||||
if statConn != nil {
|
if statConn != nil {
|
||||||
counter = statConn.WriteCounter
|
counter = statConn.WriteCounter
|
||||||
}
|
}
|
||||||
err = encoding.XtlsWrite(clientReader, serverWriter, timer, netConn, counter, ctx, &userUUID, &numberOfPacketToFilter,
|
err = encoding.XtlsWrite(clientReader, serverWriter, timer, netConn, counter, ctx, &userUUID, &numberOfPacketToFilter,
|
||||||
&enableXtls, &isTLS12orAbove, &isTLS, &cipher, &remainingServerHello)
|
&enableXtls, &isTLS12orAbove, &isTLS, &cipher, &remainingServerHello)
|
||||||
} else {
|
} else {
|
||||||
// from clientReader.ReadMultiBuffer to serverWriter.WriteMultiBufer
|
// from clientReader.ReadMultiBuffer to serverWriter.WriteMultiBufer
|
||||||
@@ -280,8 +302,8 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
|
|||||||
counter = statConn.ReadCounter
|
counter = statConn.ReadCounter
|
||||||
}
|
}
|
||||||
if requestAddons.Flow == vless.XRV {
|
if requestAddons.Flow == vless.XRV {
|
||||||
err = encoding.XtlsRead(serverReader, clientWriter, timer, netConn, rawConn, counter, ctx, account.ID.Bytes(),
|
err = encoding.XtlsRead(serverReader, clientWriter, timer, netConn, rawConn, input, rawInput, counter, ctx, account.ID.Bytes(),
|
||||||
&numberOfPacketToFilter, &enableXtls, &isTLS12orAbove, &isTLS, &cipher, &remainingServerHello)
|
&numberOfPacketToFilter, &enableXtls, &isTLS12orAbove, &isTLS, &cipher, &remainingServerHello)
|
||||||
} else {
|
} else {
|
||||||
if requestAddons.Flow != vless.XRS {
|
if requestAddons.Flow != vless.XRS {
|
||||||
ctx = session.ContextWithInbound(ctx, nil)
|
ctx = session.ContextWithInbound(ctx, nil)
|
||||||
|
@@ -252,7 +252,9 @@ func (v *TimedUserValidator) BurnTaintFuse(userHash []byte) error {
|
|||||||
return ErrNotFound
|
return ErrNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ShouldShowLegacyWarn will return whether a Legacy Warning should be shown
|
/*
|
||||||
|
ShouldShowLegacyWarn will return whether a Legacy Warning should be shown
|
||||||
|
|
||||||
Not guaranteed to only return true once for every inbound, but it is okay.
|
Not guaranteed to only return true once for every inbound, but it is okay.
|
||||||
*/
|
*/
|
||||||
func (v *TimedUserValidator) ShouldShowLegacyWarn() bool {
|
func (v *TimedUserValidator) ShouldShowLegacyWarn() bool {
|
||||||
|
@@ -1,8 +1,9 @@
|
|||||||
// Package kcp - A Fast and Reliable ARQ Protocol
|
// Package kcp - A Fast and Reliable ARQ Protocol
|
||||||
//
|
//
|
||||||
// Acknowledgement:
|
// Acknowledgement:
|
||||||
// skywind3000@github for inventing the KCP protocol
|
//
|
||||||
// xtaci@github for translating to Golang
|
// skywind3000@github for inventing the KCP protocol
|
||||||
|
// xtaci@github for translating to Golang
|
||||||
package kcp
|
package kcp
|
||||||
|
|
||||||
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
|
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
|
||||||
|
@@ -140,8 +140,8 @@ func (s *clientConnections) openConnection(ctx context.Context, destAddr net.Add
|
|||||||
}
|
}
|
||||||
|
|
||||||
quicConfig := &quic.Config{
|
quicConfig := &quic.Config{
|
||||||
ConnectionIDLength: 12,
|
ConnectionIDLength: 12,
|
||||||
KeepAlivePeriod: 0,
|
KeepAlivePeriod: 0,
|
||||||
HandshakeIdleTimeout: time.Second * 8,
|
HandshakeIdleTimeout: time.Second * 8,
|
||||||
MaxIdleTimeout: time.Second * 300,
|
MaxIdleTimeout: time.Second * 300,
|
||||||
Tracer: qlog.NewTracer(func(_ logging.Perspective, connID []byte) io.WriteCloser {
|
Tracer: qlog.NewTracer(func(_ logging.Perspective, connID []byte) io.WriteCloser {
|
||||||
|
@@ -106,8 +106,8 @@ func Listen(ctx context.Context, address net.Address, port net.Port, streamSetti
|
|||||||
quicConfig := &quic.Config{
|
quicConfig := &quic.Config{
|
||||||
ConnectionIDLength: 12,
|
ConnectionIDLength: 12,
|
||||||
KeepAlivePeriod: 0,
|
KeepAlivePeriod: 0,
|
||||||
HandshakeIdleTimeout: time.Second * 8,
|
HandshakeIdleTimeout: time.Second * 8,
|
||||||
MaxIdleTimeout: time.Second * 300,
|
MaxIdleTimeout: time.Second * 300,
|
||||||
MaxIncomingStreams: 32,
|
MaxIncomingStreams: 32,
|
||||||
MaxIncomingUniStreams: -1,
|
MaxIncomingUniStreams: -1,
|
||||||
Tracer: qlog.NewTracer(func(_ logging.Perspective, connID []byte) io.WriteCloser {
|
Tracer: qlog.NewTracer(func(_ logging.Perspective, connID []byte) io.WriteCloser {
|
||||||
|
@@ -1,11 +1,12 @@
|
|||||||
package internet
|
package internet
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/xtls/xray-core/common/net"
|
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
"os"
|
"os"
|
||||||
"syscall"
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/xtls/xray-core/common/net"
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@@ -78,11 +78,11 @@ func applyOutboundSocketOptions(network string, address string, fd uintptr, conf
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.TcpCongestion != "" {
|
if config.TcpCongestion != "" {
|
||||||
if err := syscall.SetsockoptString(int(fd), syscall.SOL_TCP, syscall.TCP_CONGESTION, config.TcpCongestion); err != nil {
|
if err := syscall.SetsockoptString(int(fd), syscall.SOL_TCP, syscall.TCP_CONGESTION, config.TcpCongestion); err != nil {
|
||||||
return newError("failed to set TCP_CONGESTION", err)
|
return newError("failed to set TCP_CONGESTION", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.Tproxy.IsEnabled() {
|
if config.Tproxy.IsEnabled() {
|
||||||
@@ -128,11 +128,11 @@ func applyInboundSocketOptions(network string, fd uintptr, config *SocketConfig)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.TcpCongestion != "" {
|
if config.TcpCongestion != "" {
|
||||||
if err := syscall.SetsockoptString(int(fd), syscall.SOL_TCP, syscall.TCP_CONGESTION, config.TcpCongestion); err != nil {
|
if err := syscall.SetsockoptString(int(fd), syscall.SOL_TCP, syscall.TCP_CONGESTION, config.TcpCongestion); err != nil {
|
||||||
return newError("failed to set TCP_CONGESTION", err)
|
return newError("failed to set TCP_CONGESTION", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.Tproxy.IsEnabled() {
|
if config.Tproxy.IsEnabled() {
|
||||||
|
@@ -3,11 +3,12 @@ package tls
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
gotls "crypto/tls"
|
gotls "crypto/tls"
|
||||||
utls "github.com/refraction-networking/utls"
|
|
||||||
"google.golang.org/grpc/credentials"
|
|
||||||
"net"
|
"net"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
utls "github.com/refraction-networking/utls"
|
||||||
|
"google.golang.org/grpc/credentials"
|
||||||
)
|
)
|
||||||
|
|
||||||
// grpcUtlsInfo contains the auth information for a TLS authenticated connection.
|
// grpcUtlsInfo contains the auth information for a TLS authenticated connection.
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
/*Package websocket implements WebSocket transport
|
/*
|
||||||
|
Package websocket implements WebSocket transport
|
||||||
|
|
||||||
WebSocket transport implements an HTTP(S) compliable, surveillance proof transport method with plausible deniability.
|
WebSocket transport implements an HTTP(S) compliable, surveillance proof transport method with plausible deniability.
|
||||||
*/
|
*/
|
||||||
|
@@ -2,7 +2,6 @@ package xtls
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
xtls "github.com/xtls/go"
|
xtls "github.com/xtls/go"
|
||||||
|
|
||||||
"github.com/xtls/xray-core/common/net"
|
"github.com/xtls/xray-core/common/net"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user