Compare commits

...

28 Commits

Author SHA1 Message Date
RPRX
1bf3a632ca v1.7.2 2023-01-07 17:51:40 +00:00
RPRX
ff5ce767df Revert "add file soft link path resolve support (#1482)" (#1495)
This reverts commit eaf401eda9.
2023-01-07 15:11:23 +00:00
RPRX
8c0d3c0257 XTLS Vision supports acceptProxyProtocol (test needed)
Fixes https://github.com/XTLS/Xray-core/issues/1339
2023-01-07 11:01:53 +00:00
yuhan6665
9bc1564b0a Update v1.7.1 and dependencies 2023-01-06 21:10:47 -05:00
dependabot[bot]
6a85682716 Bump golang.org/x/crypto from 0.4.0 to 0.5.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.4.0 to 0.5.0.
- [Release notes](https://github.com/golang/crypto/releases)
- [Commits](https://github.com/golang/crypto/compare/v0.4.0...v0.5.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-06 20:16:38 -05:00
RPRX
6f61021f7a XTLS Vision processes struct TLS Conn's input and rawInput
Fixes https://github.com/XTLS/Xray-core/issues/1444
2023-01-06 05:37:16 +00:00
dependabot[bot]
c0ceebe709 Bump github.com/sagernet/sing from 0.1.1 to 0.1.2
Bumps [github.com/sagernet/sing](https://github.com/sagernet/sing) from 0.1.1 to 0.1.2.
- [Release notes](https://github.com/sagernet/sing/releases)
- [Commits](https://github.com/sagernet/sing/compare/v0.1.1...v0.1.2)

---
updated-dependencies:
- dependency-name: github.com/sagernet/sing
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-03 19:44:22 -05:00
Nanyu
eaf401eda9 add file soft link path resolve support (#1482)
* add file soft link path resolve

* add configuration file soft link path resolve support
2023-01-03 10:52:11 -05:00
Senis John
11ec77bc76 update: release.yml
Replace old download URL
2022-12-29 23:50:36 -05:00
thank243
3b2ff95a9b update: release.yml (#1464)
* update: release.yml

* update: release.yml
2022-12-29 22:34:49 -05:00
yuhan6665
3db7d44fc2 Update v1.7.0 and denpendencies 2022-12-25 19:47:53 -05:00
yuhan6665
c4fbdf1b78 Run core/format.go 2022-12-25 19:47:53 -05:00
PMExtra
c9b6fc0104 Add custom header support for HTTP proxy 2022-12-18 21:48:23 -05:00
dependabot[bot]
d7ac6946d2 Bump github.com/sagernet/sing from 0.1.0 to 0.1.1
Bumps [github.com/sagernet/sing](https://github.com/sagernet/sing) from 0.1.0 to 0.1.1.
- [Release notes](https://github.com/sagernet/sing/releases)
- [Commits](https://github.com/sagernet/sing/compare/v0.1.0...v0.1.1)

---
updated-dependencies:
- dependency-name: github.com/sagernet/sing
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-18 21:17:30 -05:00
yuhan6665
48a75fc340 Add retry for release steps to download geofiles 2022-12-18 21:16:53 -05:00
pocketW
a55cf1d0bf fix: email inconsistent 2022-12-15 08:35:07 -05:00
yuhan6665
f35ded79ad Vision only reject TCP command for VLESS-TCP-TLS
UDP and MUX command currently has no flow value.
Also the character is the same with or without XTLS
2022-12-12 21:20:01 -05:00
yuhan6665
f3104b8684 Update v1.6.6 and denpendencies 2022-12-11 10:03:33 -05:00
yuhan6665
bc4de6a026 Fix VLESS client doesn't handle traffic if not send data first
Certain ssh, mySQL and reverse proxy need server data first in a connection
2022-12-11 09:44:40 -05:00
renahita6
3e4e050313 Fixed a bug that mux.Session could not be properly closed when receiving an End status. 2022-12-10 18:59:51 -05:00
dependabot[bot]
b8e8229242 Bump github.com/lucas-clemente/quic-go from 0.31.0 to 0.31.1
Bumps [github.com/lucas-clemente/quic-go](https://github.com/lucas-clemente/quic-go) from 0.31.0 to 0.31.1.
- [Release notes](https://github.com/lucas-clemente/quic-go/releases)
- [Changelog](https://github.com/lucas-clemente/quic-go/blob/master/Changelog.md)
- [Commits](https://github.com/lucas-clemente/quic-go/compare/v0.31.0...v0.31.1)

---
updated-dependencies:
- dependency-name: github.com/lucas-clemente/quic-go
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-09 19:21:36 -05:00
dependabot[bot]
a8fa5bf516 Bump golang.org/x/crypto from 0.3.0 to 0.4.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.3.0 to 0.4.0.
- [Release notes](https://github.com/golang/crypto/releases)
- [Commits](https://github.com/golang/crypto/compare/v0.3.0...v0.4.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-07 22:52:18 -05:00
dependabot[bot]
4a3f3ef775 Bump golang.org/x/net from 0.3.0 to 0.4.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.3.0 to 0.4.0.
- [Release notes](https://github.com/golang/net/releases)
- [Commits](https://github.com/golang/net/compare/v0.3.0...v0.4.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-07 22:51:18 -05:00
dependabot[bot]
5858726233 Bump golang.org/x/net from 0.2.0 to 0.3.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.2.0 to 0.3.0.
- [Release notes](https://github.com/golang/net/releases)
- [Commits](https://github.com/golang/net/compare/v0.2.0...v0.3.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-06 21:16:51 -05:00
dependabot[bot]
b13c3f053a Bump golang.org/x/sys from 0.2.0 to 0.3.0
Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.2.0 to 0.3.0.
- [Release notes](https://github.com/golang/sys/releases)
- [Commits](https://github.com/golang/sys/compare/v0.2.0...v0.3.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sys
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-04 23:17:08 -05:00
yuhan6665
2e30093ffd Enforce specific none flow for xtls vision
In the past, when user open xtls vision on the server side, plain vless+tls can connect.
Pure tls is known to have certain tls in tls characters.
Now  server need to specify "xtls-rprx-vision,none" for it be able usable on the same port.
2022-12-04 23:15:36 -05:00
yuhan6665
1d7c40d728 Enable Xtls Vision (Direct not Splice) for any inbound connection
Before this change, Vision client need a pure inbound like socks or http.
After this change, it will support any inbound.
This is useful in traffic forwarder use case inside China.
2022-12-04 23:15:36 -05:00
Senis John
143229b148 update: Implement the proxy.UserManager of ss2022 2022-12-03 21:19:31 -05:00
29 changed files with 527 additions and 182 deletions

View File

@@ -161,21 +161,25 @@ jobs:
mv xray xray.exe
- name: Prepare to release
run: |
cp ${GITHUB_WORKSPACE}/README.md ./build_assets/README.md
cp ${GITHUB_WORKSPACE}/LICENSE ./build_assets/LICENSE
LIST=('geoip geoip geoip' 'domain-list-community dlc geosite')
for i in "${LIST[@]}"
do
INFO=($(echo $i | awk 'BEGIN{FS=" ";OFS=" "} {print $1,$2,$3}'))
LASTEST_TAG="$(curl -sL "https://api.github.com/repos/v2fly/${INFO[0]}/releases" | jq -r ".[0].tag_name" || echo "latest")"
FILE_NAME="${INFO[2]}.dat"
echo -e "Downloading ${FILE_NAME}..."
curl -L "https://github.com/v2fly/${INFO[0]}/releases/download/${LASTEST_TAG}/${INFO[1]}.dat" -o ./build_assets/${FILE_NAME}
echo -e "Verifying HASH key..."
HASH="$(curl -sL "https://github.com/v2fly/${INFO[0]}/releases/download/${LASTEST_TAG}/${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
uses: nick-fields/retry@v2
with:
timeout_minutes: 60
retry_wait_seconds: 60
max_attempts: 60
command: |
cp ${GITHUB_WORKSPACE}/README.md ./build_assets/README.md
cp ${GITHUB_WORKSPACE}/LICENSE ./build_assets/LICENSE
LIST=('geoip geoip geoip' 'domain-list-community dlc geosite')
for i in "${LIST[@]}"
do
INFO=($(echo $i | awk 'BEGIN{FS=" ";OFS=" "} {print $1,$2,$3}'))
FILE_NAME="${INFO[2]}.dat"
echo -e "Downloading https://raw.githubusercontent.com/v2fly/${INFO[0]}/release/${INFO[1]}.dat..."
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
shell: bash

View File

@@ -7,8 +7,8 @@ import (
"time"
"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/log"
"github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/common/session"
"github.com/xtls/xray-core/core"

View File

@@ -355,6 +355,7 @@ func (m *ClientWorker) handleStatusEnd(meta *FrameMetadata, reader *buf.Buffered
common.Interrupt(s.input)
common.Interrupt(s.output)
}
common.Interrupt(s.input)
s.Close()
}
if meta.Option.Has(OptionData) {

View File

@@ -202,6 +202,7 @@ func (w *ServerWorker) handleStatusEnd(meta *FrameMetadata, reader *buf.Buffered
common.Interrupt(s.input)
common.Interrupt(s.output)
}
common.Interrupt(s.input)
s.Close()
}
if meta.Option.Has(OptionData) {

View File

@@ -26,7 +26,8 @@ func MustFromContext(ctx context.Context) *Instance {
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
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,
and may break at any time.
*/
func toContext(ctx context.Context, v *Instance) context.Context {
if FromContext(ctx) != v {
@@ -43,7 +43,8 @@ func toContext(ctx context.Context, v *Instance) context.Context {
return ctx
}
/*ToBackgroundDetachedContext create a detached context from another context
/*
ToBackgroundDetachedContext create a detached context from another context
Internal API
*/
func ToBackgroundDetachedContext(ctx context.Context) context.Context {

View File

@@ -18,7 +18,7 @@ import (
)
var (
version = "1.6.5"
version = "1.7.2"
build = "Custom"
codename = "Xray, Penetrates Everything."
intro = "A unified platform for anti-censorship."

35
go.mod
View File

@@ -8,24 +8,24 @@ require (
github.com/golang/protobuf v1.5.2
github.com/google/go-cmp v0.5.9
github.com/gorilla/websocket v1.5.0
github.com/lucas-clemente/quic-go v0.31.0
github.com/marten-seemann/qtls-go1-18 v0.1.3
github.com/lucas-clemente/quic-go v0.31.1
github.com/marten-seemann/qtls-go1-18 v0.1.4
github.com/miekg/dns v1.1.50
github.com/pelletier/go-toml v1.9.5
github.com/pires/go-proxyproto v0.6.2
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/wireguard-go v0.0.0-20221116151939-c99467f53f2c
github.com/seiflotfy/cuckoofilter v0.0.0-20220411075957-e3b120b3f5fb
github.com/stretchr/testify v1.8.1
github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e
github.com/xtls/go v0.0.0-20220914232946-0441cf4cf837
go.starlark.net v0.0.0-20221028183056-acb66ad56dd2
golang.org/x/crypto v0.3.0
golang.org/x/net v0.2.0
go.starlark.net v0.0.0-20230105143730-d7da88764354
golang.org/x/crypto v0.5.0
golang.org/x/net v0.5.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/protobuf v1.28.1
gvisor.dev/gvisor v0.0.0-20220901235040-6ca97ef2ce1c
@@ -39,21 +39,22 @@ require (
github.com/francoispqt/gojay v1.2.13 // indirect
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect
github.com/google/btree v1.1.2 // indirect
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 // indirect
github.com/klauspost/compress v1.15.12 // indirect
github.com/klauspost/cpuid/v2 v2.2.1 // indirect
github.com/google/pprof v0.0.0-20221219190121-3cb0bae90811 // indirect
github.com/klauspost/compress v1.15.14 // indirect
github.com/klauspost/cpuid/v2 v2.2.3 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/marten-seemann/qtls-go1-19 v0.1.1 // indirect
github.com/onsi/ginkgo/v2 v2.5.1 // indirect
github.com/marten-seemann/qtls-go1-19 v0.1.2 // indirect
github.com/onsi/ginkgo/v2 v2.6.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 // 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/text v0.4.0 // indirect
golang.org/x/time v0.2.0 // indirect
golang.org/x/tools v0.3.0 // indirect
google.golang.org/genproto v0.0.0-20221118155620-16455021b5e6 // indirect
golang.org/x/text v0.6.0 // indirect
golang.org/x/time v0.3.0 // indirect
golang.org/x/tools v0.5.0 // 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.v3 v3.0.1 // indirect
lukechampine.com/blake3 v1.1.7 // indirect

86
go.sum
View File

@@ -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/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-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ=
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo=
github.com/google/pprof v0.0.0-20221219190121-3cb0bae90811 h1:wORs2YN3R3ona/CXYuTvLM31QlgoNKHvlCNuArCDDCU=
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 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg=
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/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.15.12 h1:YClS/PImqYbn+UILDnqxQCZ3RehC9N318SU3kElDUEM=
github.com/klauspost/compress v1.15.12/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM=
github.com/klauspost/compress v1.15.13 h1:NFn1Wr8cfnenSJSA46lLq4wHCcBzKTSjnBIexDMMOV0=
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.2.1 h1:U33DW0aiEj633gHYw3LoDNfkDiYnE5Q8M/TKJn2f2jI=
github.com/klauspost/cpuid/v2 v2.2.1/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
github.com/klauspost/cpuid/v2 v2.2.2 h1:xPMwiykqNK9VK0NYC3+jTMYv9I6Vl3YdjZgPZKG3zO0=
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.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
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.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
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.0/go.mod h1:0wFbizLgYzqHqtlyxyCaJKlE7bYgE6JQ+54TLd/Dq2g=
github.com/lucas-clemente/quic-go v0.31.1 h1:O8Od7hfioqq0PMYHDyBkxU2aA7iZ2W9pjbrWuja2YR4=
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/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.3/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.1/go.mod h1:5HTDWtVudo/WFsHKRNuOhWlbdjrfs5JHrYb0wIJqGpI=
github.com/marten-seemann/qtls-go1-18 v0.1.4 h1:ogomB+lWV3Vmwiu6RTwDVTMGx+9j7SEi98e8QB35Its=
github.com/marten-seemann/qtls-go1-18 v0.1.4/go.mod h1:mJttiymBAByA49mhlNZZGrH5u1uXYZJ+RW28Py7f4m4=
github.com/marten-seemann/qtls-go1-19 v0.1.2 h1:ZevAEqKXH0bZmoOBPiqX2h5rhQ7cbZi+X+rlq2JUbCE=
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/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
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/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo=
github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
github.com/onsi/ginkgo/v2 v2.5.1 h1:auzK7OI497k6x4OvWq+TKAcpcSAlod0doAH72oIN0Jw=
github.com/onsi/ginkgo/v2 v2.5.1/go.mod h1:63DOGlLAH8+REH8jUGdL3YpCpu7JODesutUjdENfUAc=
github.com/onsi/gomega v1.24.0 h1:+0glovB9Jd6z3VR+ScSwQqXVTIfJcGA9UBM8yzQxhqg=
github.com/onsi/ginkgo/v2 v2.6.1 h1:1xQPCjcqYw/J5LchOcp4/2q/jzJFjiAOc25chhnDw+Q=
github.com/onsi/ginkgo/v2 v2.6.1/go.mod h1:yjiuMwPokqY1XauOgju45q3sJt6VzQ/Fict1LFVcsAo=
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/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
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/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
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.0/go.mod h1:zvgDYKI+vCAW9RyfyrKTgleI+DOa8lzHMPC7VZo3OL4=
github.com/sagernet/sing v0.1.2 h1:rp5AqY23P0klk2IaLEI0/WJsD8FTVlv9TaI2QSL6TDA=
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/go.mod h1:O5LtOs8Ivw686FqLpO0Zu+A0ROVE15VeqEK3yDRRAms=
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/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
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-20221028183056-acb66ad56dd2/go.mod h1:kIVgS18CjmEC3PqMd5kaJSGEifyV/CeB9x506ZJ1Vbk=
go.starlark.net v0.0.0-20221205180719-3fd0dac74452 h1:JZtNuL6LPB+scU5yaQ6hqRlJFRiddZm2FwRt2AQqtHA=
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/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
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-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.3.0 h1:a06MkbcxBrEFc0w0QIZWXrH/9cCX6KJyWbBOIwAn+7A=
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE=
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-20221126150942-6ab00d035af9 h1:yZNXmy+j/JpX19vZkVktWqAo7Gny4PBWYYK3zskGpx4=
golang.org/x/exp v0.0.0-20221126150942-6ab00d035af9/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
golang.org/x/exp v0.0.0-20221217163422-3c43f8badb15 h1:5oN1Pz/eDhCpbMbLstvIPa0b/BEQo6g6nwV3pLjfM6w=
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-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
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-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
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.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw=
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-20181017192945-9dcd33a902f4/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-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.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18=
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-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.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.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k=
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-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.2.0 h1:52I/1L54xyEQAYdtcSuxtiT84KGYTBGXwayxmIpNJhE=
golang.org/x/time v0.2.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
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-20180917221912-90fa682c2a6e/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.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.3.0 h1:SrNbZl6ECOS1qFzgTdQfWXZM9XBkiA6tkFrH9YSTPHM=
golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k=
golang.org/x/tools v0.4.0 h1:7mTAgkunk3fr4GAloyyCasadO6h9zSsQZbwvcaIciV4=
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-20191011141410-1b5146add898/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-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-20221118155620-16455021b5e6 h1:a2S6M0+660BgMNl++4JPlcAO/CjkqYItDEZwkoDQK7c=
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 h1:jmIfw8+gSvXcZSgaFAGyInDXeWzUhvYH57G/5GKMn70=
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.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=
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/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 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/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

View File

@@ -53,6 +53,7 @@ type HTTPRemoteConfig struct {
type HTTPClientConfig struct {
Servers []*HTTPRemoteConfig `json:"servers"`
Headers map[string]string `json:"headers"`
}
func (v *HTTPClientConfig) Build() (proto.Message, error) {
@@ -77,5 +78,12 @@ func (v *HTTPClientConfig) Build() (proto.Message, error) {
}
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
}

View File

@@ -107,7 +107,7 @@ func buildShadowsocks2022(v *ShadowsocksServerConfig) (proto.Message, error) {
config.Email = v.Email
return config, nil
}
if v.Cipher == "" {
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.Key = v.Password
config.Network = v.NetworkList.Build()
for _, user := range v.Users {
if user.Cipher != "" {
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")
}
config.Destinations = append(config.Destinations, &shadowsocks_2022.RelayDestination{
Key: user.Password,
Email: user.Email,
Key: user.Password,
Email: user.Email,
Address: user.Address.Build(),
Port: uint32(user.Port),
Port: uint32(user.Port),
})
}
return config, nil

View File

@@ -533,7 +533,7 @@ type SocketConfig struct {
DialerProxy string `json:"dialerProxy"`
TCPKeepAliveInterval int32 `json:"tcpKeepAliveInterval"`
TCPKeepAliveIdle int32 `json:"tcpKeepAliveIdle"`
TCPCongestion string `json:"tcpCongestion"`
TCPCongestion string `json:"tcpCongestion"`
}
// Build implements Buildable.
@@ -582,7 +582,7 @@ func (c *SocketConfig) Build() (*internet.SocketConfig, error) {
DialerProxy: c.DialerProxy,
TcpKeepAliveInterval: c.TCPKeepAliveInterval,
TcpKeepAliveIdle: c.TCPKeepAliveIdle,
TcpCongestion: c.TCPCongestion,
TcpCongestion: c.TCPCongestion,
}, nil
}

View File

@@ -4,6 +4,7 @@ import (
"encoding/json"
"runtime"
"strconv"
"strings"
"syscall"
"github.com/golang/protobuf/proto"
@@ -52,7 +53,15 @@ func (c *VLessInboundConfig) Build() (proto.Message, error) {
}
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.XRS:
return nil, newError(`VLESS clients: inbound doesn't support "xtls-rprx-splice" in this version, please use "xtls-rprx-direct" instead`)

View File

@@ -2,12 +2,14 @@ package http
import (
"bufio"
"bytes"
"context"
"encoding/base64"
"io"
"net/http"
"net/url"
"sync"
"text/template"
"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/buf"
@@ -30,6 +32,7 @@ import (
type Client struct {
serverPicker protocol.ServerPicker
policyManager policy.Manager
header []*Header
}
type h2Conn struct {
@@ -60,6 +63,7 @@ func NewClient(ctx context.Context, config *ClientConfig) (*Client, error) {
return &Client{
serverPicker: protocol.NewRoundRobinServerPicker(serverList),
policyManager: v.GetFeature(policy.ManagerType()).(policy.Manager),
header: config.Header,
}, nil
}
@@ -88,12 +92,17 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter
buf.ReleaseMulti(mbuf)
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 {
server := c.serverPicker.PickServer()
dest := server.Destination()
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 _, ok := netConn.(*http2Conn); !ok {
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
}
// 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
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{
Method: http.MethodConnect,
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)))
}
for _, h := range header {
req.Header.Set(h.Key, h.Value)
}
connectHTTP1 := func(rawConn net.Conn) (net.Conn, error) {
req.Header.Set("Proxy-Connection", "Keep-Alive")

View File

@@ -150,6 +150,61 @@ func (x *ServerConfig) GetUserLevel() uint32 {
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.
type ClientConfig struct {
state protoimpl.MessageState
@@ -158,12 +213,13 @@ type ClientConfig struct {
// Sever is a list of HTTP server addresses.
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() {
*x = ClientConfig{}
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.StoreMessageInfo(mi)
}
@@ -176,7 +232,7 @@ func (x *ClientConfig) String() string {
func (*ClientConfig) ProtoMessage() {}
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 {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -189,7 +245,7 @@ func (x *ClientConfig) ProtoReflect() protoreflect.Message {
// Deprecated: Use ClientConfig.ProtoReflect.Descriptor instead.
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 {
@@ -199,6 +255,13 @@ func (x *ClientConfig) GetServer() []*protocol.ServerEndpoint {
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_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,
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,
0x01, 0x22, 0x4c, 0x0a, 0x0c, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69,
0x67, 0x12, 0x3c, 0x0a, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x03, 0x28,
0x0b, 0x32, 0x24, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x45,
0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x06, 0x73, 0x65, 0x72, 0x76, 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,
0x01, 0x22, 0x30, 0x0a, 0x06, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 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, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61,
0x6c, 0x75, 0x65, 0x22, 0x7d, 0x0a, 0x0c, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e,
0x66, 0x69, 0x67, 0x12, 0x3c, 0x0a, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20,
0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f,
0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65,
0x72, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65,
0x72, 0x12, 0x2f, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x02, 0x20, 0x03, 0x28,
0x0b, 0x32, 0x17, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x68,
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 (
@@ -252,22 +321,24 @@ func file_proxy_http_config_proto_rawDescGZIP() []byte {
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{}{
(*Account)(nil), // 0: xray.proxy.http.Account
(*ServerConfig)(nil), // 1: xray.proxy.http.ServerConfig
(*ClientConfig)(nil), // 2: xray.proxy.http.ClientConfig
nil, // 3: xray.proxy.http.ServerConfig.AccountsEntry
(*protocol.ServerEndpoint)(nil), // 4: xray.common.protocol.ServerEndpoint
(*Header)(nil), // 2: xray.proxy.http.Header
(*ClientConfig)(nil), // 3: xray.proxy.http.ClientConfig
nil, // 4: xray.proxy.http.ServerConfig.AccountsEntry
(*protocol.ServerEndpoint)(nil), // 5: xray.common.protocol.ServerEndpoint
}
var file_proxy_http_config_proto_depIdxs = []int32{
3, // 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
2, // [2:2] is the sub-list for method output_type
2, // [2:2] is the sub-list for method input_type
2, // [2:2] is the sub-list for extension type_name
2, // [2:2] is the sub-list for extension extendee
0, // [0:2] is the sub-list for field type_name
4, // 0: xray.proxy.http.ServerConfig.accounts:type_name -> xray.proxy.http.ServerConfig.AccountsEntry
5, // 1: xray.proxy.http.ClientConfig.server:type_name -> xray.common.protocol.ServerEndpoint
2, // 2: xray.proxy.http.ClientConfig.header:type_name -> xray.proxy.http.Header
3, // [3:3] is the sub-list for method output_type
3, // [3:3] is the sub-list for method input_type
3, // [3:3] is the sub-list for extension 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() }
@@ -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{} {
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 {
case 0:
return &v.state
@@ -319,7 +402,7 @@ func file_proxy_http_config_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_proxy_http_config_proto_rawDesc,
NumEnums: 0,
NumMessages: 4,
NumMessages: 5,
NumExtensions: 0,
NumServices: 0,
},

View File

@@ -21,8 +21,14 @@ message ServerConfig {
uint32 user_level = 4;
}
message Header {
string key = 1;
string value = 2;
}
// ClientConfig is the protobuf config for HTTP proxy client.
message ClientConfig {
// Sever is a list of HTTP server addresses.
repeated xray.common.protocol.ServerEndpoint server = 1;
repeated Header header = 2;
}

View 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
}

View File

@@ -4,6 +4,8 @@ import (
"context"
"encoding/base64"
"strconv"
"strings"
"sync"
"github.com/sagernet/sing-shadowsocks/shadowaead_2022"
C "github.com/sagernet/sing/common"
@@ -31,6 +33,7 @@ func init() {
}
type MultiUserInbound struct {
sync.Mutex
networks []net.Network
users []*User
service *shadowaead_2022.MultiService[int]
@@ -78,6 +81,72 @@ func NewMultiServer(ctx context.Context, config *MultiUserServerConfig) (*MultiU
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 {
return i.networks
}

View File

@@ -31,10 +31,12 @@ const (
Version = byte(0)
)
var tls13SupportedVersions = []byte{0x00, 0x2b, 0x00, 0x02, 0x03, 0x04}
var tlsClientHandShakeStart = []byte{0x16, 0x03}
var tlsServerHandShakeStart = []byte{0x16, 0x03, 0x03}
var tlsApplicationDataStart = []byte{0x17, 0x03, 0x03}
var (
tls13SupportedVersions = []byte{0x00, 0x2b, 0x00, 0x02, 0x03, 0x04}
tlsClientHandShakeStart = []byte{0x16, 0x03}
tlsServerHandShakeStart = []byte{0x16, 0x03, 0x03}
tlsApplicationDataStart = []byte{0x17, 0x03, 0x03}
)
var addrParser = protocol.NewAddressParser(
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
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,
isTLS12orAbove *bool, isTLS *bool, cipher *uint16, remainingServerHello *int32) error {
func XtlsRead(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater, conn net.Conn, rawConn syscall.RawConn,
input *bytes.Reader, rawInput *bytes.Buffer,
counter stats.Counter, ctx context.Context, userUUID []byte, numberOfPacketToFilter *int, enableXtls *bool,
isTLS12orAbove *bool, isTLS *bool, cipher *uint16, remainingServerHello *int32,
) error {
err := func() error {
var ct stats.Counter
filterUUID := true
@@ -260,8 +264,8 @@ func XtlsRead(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater
for {
if shouldSwitchToDirectCopy {
shouldSwitchToDirectCopy = false
if runtime.GOOS == "linux" || runtime.GOOS == "android" {
if inbound := session.InboundFromContext(ctx); inbound != nil && inbound.Conn != nil {
if inbound := session.InboundFromContext(ctx); inbound != nil && inbound.Conn != nil && (runtime.GOOS == "linux" || runtime.GOOS == "android") {
if _, ok := inbound.User.Account.(*vless.MemoryAccount); inbound.User.Account == nil || ok {
iConn := inbound.Conn
statConn, ok := iConn.(*stat.CounterConnection)
if ok {
@@ -281,11 +285,7 @@ func XtlsRead(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater
statConn.WriteCounter.Add(w)
}
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)
@@ -302,6 +302,17 @@ func XtlsRead(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater
} else if currentCommand == 2 {
filterUUID = false
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 {
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
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,
cipher *uint16, remainingServerHello *int32) error {
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,
cipher *uint16, remainingServerHello *int32,
) error {
err := func() error {
var ct stats.Counter
filterTlsApplicationData := true
@@ -358,7 +370,7 @@ func XtlsWrite(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdate
buffer[i] = XtlsPadding(b, command, userUUID, ctx)
break
} else if !*isTLS12orAbove && *numberOfPacketToFilter <= 0 {
//maybe tls 1.1 or 1.0
// maybe tls 1.1 or 1.0
filterTlsApplicationData = false
buffer[i] = XtlsPadding(b, 0x01, userUUID, ctx)
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
func XtlsFilterTls(buffer buf.MultiBuffer, numberOfPacketToFilter *int, enableXtls *bool, isTLS12orAbove *bool, isTLS *bool,
cipher *uint16, remainingServerHello *int32, ctx context.Context) {
func XtlsFilterTls(buffer buf.MultiBuffer, numberOfPacketToFilter *int, enableXtls *bool, isTLS12orAbove *bool, isTLS *bool,
cipher *uint16, remainingServerHello *int32, ctx context.Context,
) {
for _, b := range buffer {
*numberOfPacketToFilter--
if b.Len() >= 6 {
@@ -415,8 +428,8 @@ func XtlsFilterTls(buffer buf.MultiBuffer, numberOfPacketToFilter *int, enableXt
*isTLS = true
if b.Len() >= 79 && *remainingServerHello >= 79 {
sessionIdLen := int32(b.Byte(43))
cipherSuite := b.BytesRange(43 + sessionIdLen + 1, 43 + sessionIdLen + 3)
*cipher = uint16(cipherSuite[0]) << 8 | uint16(cipherSuite[1])
cipherSuite := b.BytesRange(43+sessionIdLen+1, 43+sessionIdLen+3)
*cipher = uint16(cipherSuite[0])<<8 | uint16(cipherSuite[1])
} else {
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]
if !ok {
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
}
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
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 {
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{
0x1301 : "TLS_AES_128_GCM_SHA256",
0x1302 : "TLS_AES_256_GCM_SHA384",
0x1303 : "TLS_CHACHA20_POLY1305_SHA256",
0x1304 : "TLS_AES_128_CCM_SHA256",
0x1305 : "TLS_AES_128_CCM_8_SHA256",
0x1301: "TLS_AES_128_GCM_SHA256",
0x1302: "TLS_AES_256_GCM_SHA384",
0x1303: "TLS_CHACHA20_POLY1305_SHA256",
0x1304: "TLS_AES_128_CCM_SHA256",
0x1305: "TLS_AES_128_CCM_8_SHA256",
}

View File

@@ -3,13 +3,17 @@ package inbound
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
import (
"bytes"
"context"
"io"
"reflect"
"strconv"
"strings"
"syscall"
"time"
"unsafe"
"github.com/pires/go-proxyproto"
"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/buf"
"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 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 {
case vless.XRO, vless.XRD, vless.XRV:
if account.Flow == requestAddons.Flow {
if accountFlow == requestAddons.Flow {
switch request.Command {
case protocol.RequestCommandMux:
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()
case protocol.RequestCommandTCP:
if requestAddons.Flow == vless.XRV {
var t reflect.Type
var p uintptr
if tlsConn, ok := iConn.(*tls.Conn); ok {
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 {
rawConn, _ = sc.SyscallConn()
}
t = reflect.TypeOf(tlsConn.Conn).Elem()
p = uintptr(unsafe.Pointer(tlsConn.Conn))
} else if _, ok := iConn.(*tls.UConn); ok {
return newError("XTLS only supports UTLS fingerprint for the outbound.").AtWarning()
} else if _, ok := iConn.(*xtls.Conn); ok {
@@ -464,6 +488,10 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s
} else {
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 {
xtlsConn.RPRX = true
xtlsConn.SHOW = xtls_show
@@ -481,7 +509,11 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s
} else {
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:
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 {
counter = statConn.ReadCounter
}
//TODO enable splice
// TODO enable splice
ctx = session.ContextWithInbound(ctx, nil)
if requestAddons.Flow == vless.XRV {
err = encoding.XtlsRead(clientReader, serverWriter, timer, netConn, rawConn, counter, ctx, account.ID.Bytes(),
&numberOfPacketToFilter, &enableXtls, &isTLS12orAbove, &isTLS, &cipher, &remainingServerHello)
err = encoding.XtlsRead(clientReader, serverWriter, timer, netConn, rawConn, input, rawInput, counter, ctx, account.ID.Bytes(),
&numberOfPacketToFilter, &enableXtls, &isTLS12orAbove, &isTLS, &cipher, &remainingServerHello)
} else {
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 {
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)
} else {
// from serverReader.ReadMultiBuffer to clientWriter.WriteMultiBufer

View File

@@ -3,8 +3,12 @@ package outbound
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
import (
"bytes"
"context"
"reflect"
"syscall"
"time"
"unsafe"
"github.com/xtls/xray-core/common"
"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 rawConn syscall.RawConn
var input *bytes.Reader
var rawInput *bytes.Buffer
allowUDP443 := false
switch requestAddons.Flow {
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 = ""
case protocol.RequestCommandTCP:
if requestAddons.Flow == vless.XRV {
var t reflect.Type
var p uintptr
if tlsConn, ok := iConn.(*tls.Conn); ok {
netConn = tlsConn.NetConn()
if sc, ok := netConn.(syscall.Conn); ok {
rawConn, _ = sc.SyscallConn()
}
t = reflect.TypeOf(tlsConn.Conn).Elem()
p = uintptr(unsafe.Pointer(tlsConn.Conn))
} else if utlsConn, ok := iConn.(*tls.UConn); ok {
netConn = utlsConn.Conn.NetConn()
if sc, ok := netConn.(syscall.Conn); ok {
rawConn, _ = sc.SyscallConn()
}
t = reflect.TypeOf(utlsConn.Conn).Elem()
p = uintptr(unsafe.Pointer(utlsConn.Conn))
} else if _, ok := iConn.(*xtls.Conn); ok {
return newError(`failed to use ` + requestAddons.Flow + `, vision "security" must be "tls"`).AtWarning()
} else {
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 {
xtlsConn.RPRX = true
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)
}
userUUID := account.ID.Bytes()
multiBuffer, err1 := clientReader.ReadMultiBuffer()
if err1 != nil {
return err1 // ...
}
if requestAddons.Flow == vless.XRV {
encoding.XtlsFilterTls(multiBuffer, &numberOfPacketToFilter, &enableXtls, &isTLS12orAbove, &isTLS, &cipher, &remainingServerHello, ctx)
if isTLS {
for i, b := range multiBuffer {
multiBuffer[i] = encoding.XtlsPadding(b, 0x00, &userUUID, ctx)
timeoutReader, ok := clientReader.(buf.TimeoutReader)
if ok {
multiBuffer, err1 := timeoutReader.ReadMultiBufferTimeout(time.Millisecond * 500)
if err1 == nil {
if requestAddons.Flow == vless.XRV {
encoding.XtlsFilterTls(multiBuffer, &numberOfPacketToFilter, &enableXtls, &isTLS12orAbove, &isTLS, &cipher, &remainingServerHello, ctx)
if isTLS {
for i, b := range multiBuffer {
multiBuffer[i] = encoding.XtlsPadding(b, 0x00, &userUUID, ctx)
}
}
}
if err := serverWriter.WriteMultiBuffer(multiBuffer); err != nil {
return err // ...
}
} else if err1 != buf.ErrReadTimeout {
return err1
}
}
if err := serverWriter.WriteMultiBuffer(multiBuffer); err != nil {
return err // ...
} else {
newError("Reader is not timeout reader, will send out vless header separately from first payload").AtDebug().WriteToLog(session.ExportIDToError(ctx))
}
// Flush; bufferWriter.WriteMultiBufer now is bufferWriter.writer.WriteMultiBuffer
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 {
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)
} else {
// 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
}
if requestAddons.Flow == vless.XRV {
err = encoding.XtlsRead(serverReader, clientWriter, timer, netConn, rawConn, counter, ctx, account.ID.Bytes(),
&numberOfPacketToFilter, &enableXtls, &isTLS12orAbove, &isTLS, &cipher, &remainingServerHello)
err = encoding.XtlsRead(serverReader, clientWriter, timer, netConn, rawConn, input, rawInput, counter, ctx, account.ID.Bytes(),
&numberOfPacketToFilter, &enableXtls, &isTLS12orAbove, &isTLS, &cipher, &remainingServerHello)
} else {
if requestAddons.Flow != vless.XRS {
ctx = session.ContextWithInbound(ctx, nil)

View File

@@ -252,7 +252,9 @@ func (v *TimedUserValidator) BurnTaintFuse(userHash []byte) error {
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.
*/
func (v *TimedUserValidator) ShouldShowLegacyWarn() bool {

View File

@@ -1,8 +1,9 @@
// Package kcp - A Fast and Reliable ARQ Protocol
//
// 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
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen

View File

@@ -140,8 +140,8 @@ func (s *clientConnections) openConnection(ctx context.Context, destAddr net.Add
}
quicConfig := &quic.Config{
ConnectionIDLength: 12,
KeepAlivePeriod: 0,
ConnectionIDLength: 12,
KeepAlivePeriod: 0,
HandshakeIdleTimeout: time.Second * 8,
MaxIdleTimeout: time.Second * 300,
Tracer: qlog.NewTracer(func(_ logging.Perspective, connID []byte) io.WriteCloser {

View File

@@ -106,8 +106,8 @@ func Listen(ctx context.Context, address net.Address, port net.Port, streamSetti
quicConfig := &quic.Config{
ConnectionIDLength: 12,
KeepAlivePeriod: 0,
HandshakeIdleTimeout: time.Second * 8,
MaxIdleTimeout: time.Second * 300,
HandshakeIdleTimeout: time.Second * 8,
MaxIdleTimeout: time.Second * 300,
MaxIncomingStreams: 32,
MaxIncomingUniStreams: -1,
Tracer: qlog.NewTracer(func(_ logging.Perspective, connID []byte) io.WriteCloser {

View File

@@ -1,11 +1,12 @@
package internet
import (
"github.com/xtls/xray-core/common/net"
"golang.org/x/sys/unix"
"os"
"syscall"
"unsafe"
"github.com/xtls/xray-core/common/net"
"golang.org/x/sys/unix"
)
const (

View File

@@ -78,11 +78,11 @@ func applyOutboundSocketOptions(network string, address string, fd uintptr, conf
}
}
if config.TcpCongestion != "" {
if err := syscall.SetsockoptString(int(fd), syscall.SOL_TCP, syscall.TCP_CONGESTION, config.TcpCongestion); err != nil {
return newError("failed to set TCP_CONGESTION", err)
}
}
if config.TcpCongestion != "" {
if err := syscall.SetsockoptString(int(fd), syscall.SOL_TCP, syscall.TCP_CONGESTION, config.TcpCongestion); err != nil {
return newError("failed to set TCP_CONGESTION", err)
}
}
}
if config.Tproxy.IsEnabled() {
@@ -128,11 +128,11 @@ func applyInboundSocketOptions(network string, fd uintptr, config *SocketConfig)
}
}
if config.TcpCongestion != "" {
if err := syscall.SetsockoptString(int(fd), syscall.SOL_TCP, syscall.TCP_CONGESTION, config.TcpCongestion); err != nil {
return newError("failed to set TCP_CONGESTION", err)
}
}
if config.TcpCongestion != "" {
if err := syscall.SetsockoptString(int(fd), syscall.SOL_TCP, syscall.TCP_CONGESTION, config.TcpCongestion); err != nil {
return newError("failed to set TCP_CONGESTION", err)
}
}
}
if config.Tproxy.IsEnabled() {

View File

@@ -3,11 +3,12 @@ package tls
import (
"context"
gotls "crypto/tls"
utls "github.com/refraction-networking/utls"
"google.golang.org/grpc/credentials"
"net"
"net/url"
"strconv"
utls "github.com/refraction-networking/utls"
"google.golang.org/grpc/credentials"
)
// grpcUtlsInfo contains the auth information for a TLS authenticated connection.

View File

@@ -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.
*/

View File

@@ -2,7 +2,6 @@ package xtls
import (
xtls "github.com/xtls/go"
"github.com/xtls/xray-core/common/net"
)