Compare commits

..

18 Commits

Author SHA1 Message Date
yuhan6665
8c111180d2 Add expectedResponseCode to BurstObservatory 2024-11-24 16:45:14 -05:00
RPRX
513f18bf53 v24.11.21 2024-11-21 05:47:07 +00:00
RPRX
817fa72874 XHTTP client: Add gRPC header to "stream-up" mode by default (#4042)
""Breaking"": Client uses "stream-up" mode by default when using **TLS H2** or REALITY
2024-11-21 05:45:49 +00:00
风扇滑翔翼
0a252ac15d HTTP transport: Use dest as Host if not set (#4038) 2024-11-21 05:42:19 +00:00
zonescape
6ba0dbafd7 Test: Delete temporary file afterwards (#4028) 2024-11-20 05:03:39 +00:00
风扇滑翔翼
59e5d24280 WireGuard inbound: Fix leaking session information between requests (#4030)
Fixes https://github.com/XTLS/Xray-core/issues/3948 https://github.com/XTLS/Xray-core/issues/4025
2024-11-20 05:00:40 +00:00
dependabot[bot]
7d3d6b05e3 Bump github.com/sagernet/sing from 0.5.0 to 0.5.1 (#4026)
Bumps [github.com/sagernet/sing](https://github.com/sagernet/sing) from 0.5.0 to 0.5.1.
- [Commits](https://github.com/sagernet/sing/compare/v0.5.0...v0.5.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>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-19 03:19:34 +00:00
yiguous
55e045d098 Config: Correctly marshal Address to JSON (#4021) 2024-11-19 03:18:47 +00:00
dependabot[bot]
5a96ef632d Bump google.golang.org/protobuf from 1.35.1 to 1.35.2 (#4018)
Bumps google.golang.org/protobuf from 1.35.1 to 1.35.2.

---
updated-dependencies:
- dependency-name: google.golang.org/protobuf
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-18 05:08:03 +00:00
RPRX
1f570d9cef XHTTP test: Fix Test_maxUpload
https://github.com/XTLS/Xray-core/pull/3260#issuecomment-2481946715
2024-11-18 04:53:21 +00:00
RPRX
2d7b0e8cd4 XHTTP client: Fix upload issue in "packet-up" mode inherited from SplitHTTP
Fixes https://github.com/XTLS/Xray-core/issues/3972
2024-11-17 06:03:25 +00:00
zonescape
ec1fd008c4 Chore: Refactor infra/conf.TestToCidrList() (#4017) 2024-11-14 11:04:17 -05:00
风扇滑翔翼
17825b25f2 WireGuard kernelTun: Fix multi-outbounds not work (#4015)
Fixes https://github.com/XTLS/Xray-core/issues/2817
2024-11-14 00:13:27 +00:00
zonescape
83ae38497b Chore: Drop dead code in test (#4012) 2024-11-13 10:41:54 -05:00
pinglanlu
7b4a686b74 Chore: Use a more direct and less error-prone return value (#4008)
Signed-off-by: pinglanlu <pinglanlu@outlook.com>
2024-11-12 10:44:41 -05:00
lxsq
48ac662298 Update Dockerfile to Use Multiple Config Files (#4010) 2024-11-12 10:41:42 -05:00
RPRX
1a238cbb7d REALITY client: Log invalid connections at warning level
Closes https://github.com/XTLS/Xray-core/issues/4001
2024-11-12 06:42:52 +00:00
zonescape
44b1dd0e67 Test: Change address for DNS over QUIC tests (#4002)
dns.adguard.com can be blocked in some places
2024-11-11 14:43:57 -05:00
27 changed files with 247 additions and 170 deletions

View File

@@ -22,7 +22,7 @@ VOLUME /etc/xray
ARG TZ=Asia/Shanghai
ENV TZ=$TZ
ENTRYPOINT [ "/usr/bin/xray" ]
CMD [ "-config", "/etc/xray/config.json" ]
CMD [ "-confdir", "/etc/xray/" ]
ARG flavor=v2fly
COPY --from=build --chmod=644 /$flavor /usr/share/xray

View File

@@ -14,7 +14,7 @@ import (
)
func TestQUICNameServer(t *testing.T) {
url, err := url.Parse("quic://dns.adguard.com")
url, err := url.Parse("quic://dns.adguard-dns.com")
common.Must(err)
s, err := NewQUICNameServer(url, QueryStrategy_USE_IP)
common.Must(err)
@@ -42,7 +42,7 @@ func TestQUICNameServer(t *testing.T) {
}
func TestQUICNameServerWithIPv4Override(t *testing.T) {
url, err := url.Parse("quic://dns.adguard.com")
url, err := url.Parse("quic://dns.adguard-dns.com")
common.Must(err)
s, err := NewQUICNameServer(url, QueryStrategy_USE_IP4)
common.Must(err)
@@ -65,7 +65,7 @@ func TestQUICNameServerWithIPv4Override(t *testing.T) {
}
func TestQUICNameServerWithIPv6Override(t *testing.T) {
url, err := url.Parse("quic://dns.adguard.com")
url, err := url.Parse("quic://dns.adguard-dns.com")
common.Must(err)
s, err := NewQUICNameServer(url, QueryStrategy_USE_IP6)
common.Must(err)

View File

@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.35.1
// protoc-gen-go v1.35.2
// protoc v5.28.2
// source: app/observatory/burst/config.proto
@@ -89,7 +89,8 @@ type HealthPingConfig struct {
// sampling count is the amount of recent ping results which are kept for calculation
SamplingCount int32 `protobuf:"varint,4,opt,name=samplingCount,proto3" json:"samplingCount,omitempty"`
// ping timeout, int64 values of time.Duration
Timeout int64 `protobuf:"varint,5,opt,name=timeout,proto3" json:"timeout,omitempty"`
Timeout int64 `protobuf:"varint,5,opt,name=timeout,proto3" json:"timeout,omitempty"`
ExpectedResponseCode []int32 `protobuf:"varint,6,rep,packed,name=expectedResponseCode,proto3" json:"expectedResponseCode,omitempty"`
}
func (x *HealthPingConfig) Reset() {
@@ -157,6 +158,13 @@ func (x *HealthPingConfig) GetTimeout() int64 {
return 0
}
func (x *HealthPingConfig) GetExpectedResponseCode() []int32 {
if x != nil {
return x.ExpectedResponseCode
}
return nil
}
var File_app_observatory_burst_config_proto protoreflect.FileDescriptor
var file_app_observatory_burst_config_proto_rawDesc = []byte{
@@ -173,7 +181,7 @@ var file_app_observatory_burst_config_proto_rawDesc = []byte{
0x2e, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x62, 0x75, 0x72,
0x73, 0x74, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x50, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e,
0x66, 0x69, 0x67, 0x52, 0x0a, 0x70, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22,
0xb4, 0x01, 0x0a, 0x10, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x50, 0x69, 0x6e, 0x67, 0x43, 0x6f,
0xe8, 0x01, 0x0a, 0x10, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x50, 0x69, 0x6e, 0x67, 0x43, 0x6f,
0x6e, 0x66, 0x69, 0x67, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74,
0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69,
0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63,
@@ -184,14 +192,18 @@ var file_app_observatory_burst_config_proto_rawDesc = []byte{
0x6e, 0x67, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x73,
0x61, 0x6d, 0x70, 0x6c, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07,
0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x74,
0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x42, 0x70, 0x0a, 0x1e, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72,
0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x6f,
0x72, 0x79, 0x2e, 0x62, 0x75, 0x72, 0x73, 0x74, 0x50, 0x01, 0x5a, 0x2f, 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, 0x61, 0x70, 0x70, 0x2f, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76,
0x61, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x62, 0x75, 0x72, 0x73, 0x74, 0xaa, 0x02, 0x1a, 0x58, 0x72,
0x61, 0x79, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x6f,
0x72, 0x79, 0x2e, 0x42, 0x75, 0x72, 0x73, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x32, 0x0a, 0x14, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74,
0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x18, 0x06,
0x20, 0x03, 0x28, 0x05, 0x52, 0x14, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x42, 0x70, 0x0a, 0x1e, 0x63, 0x6f,
0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x6f, 0x62, 0x73, 0x65, 0x72,
0x76, 0x61, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x62, 0x75, 0x72, 0x73, 0x74, 0x50, 0x01, 0x5a, 0x2f,
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, 0x61, 0x70, 0x70, 0x2f, 0x6f, 0x62,
0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x62, 0x75, 0x72, 0x73, 0x74, 0xaa,
0x02, 0x1a, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x4f, 0x62, 0x73, 0x65, 0x72,
0x76, 0x61, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x42, 0x75, 0x72, 0x73, 0x74, 0x62, 0x06, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x33,
}
var (

View File

@@ -26,4 +26,5 @@ message HealthPingConfig {
int32 samplingCount = 4;
// ping timeout, int64 values of time.Duration
int64 timeout = 5;
repeated int32 expectedResponseCode = 6;
}

View File

@@ -13,11 +13,12 @@ import (
// HealthPingSettings holds settings for health Checker
type HealthPingSettings struct {
Destination string `json:"destination"`
Connectivity string `json:"connectivity"`
Interval time.Duration `json:"interval"`
SamplingCount int `json:"sampling"`
Timeout time.Duration `json:"timeout"`
Destination string `json:"destination"`
Connectivity string `json:"connectivity"`
Interval time.Duration `json:"interval"`
SamplingCount int `json:"sampling"`
Timeout time.Duration `json:"timeout"`
ExpectedResponseCode []int32 `json:"expectedResponseCode"`
}
// HealthPing is the health checker for balancers
@@ -36,11 +37,12 @@ func NewHealthPing(ctx context.Context, config *HealthPingConfig) *HealthPing {
settings := &HealthPingSettings{}
if config != nil {
settings = &HealthPingSettings{
Connectivity: strings.TrimSpace(config.Connectivity),
Destination: strings.TrimSpace(config.Destination),
Interval: time.Duration(config.Interval),
SamplingCount: int(config.SamplingCount),
Timeout: time.Duration(config.Timeout),
Connectivity: strings.TrimSpace(config.Connectivity),
Destination: strings.TrimSpace(config.Destination),
Interval: time.Duration(config.Interval),
SamplingCount: int(config.SamplingCount),
Timeout: time.Duration(config.Timeout),
ExpectedResponseCode: config.ExpectedResponseCode,
}
}
if settings.Destination == "" {
@@ -48,6 +50,7 @@ func NewHealthPing(ctx context.Context, config *HealthPingConfig) *HealthPing {
// https://github.com/chromium/chromium/blob/main/components/safety_check/url_constants.cc#L10
// https://chromium.googlesource.com/chromium/src/+/refs/heads/main/components/safety_check/url_constants.cc#10
settings.Destination = "https://connectivitycheck.gstatic.com/generate_204"
settings.ExpectedResponseCode = []int32{ 204 }
}
if settings.Interval == 0 {
settings.Interval = time.Duration(1) * time.Minute
@@ -152,6 +155,7 @@ func (h *HealthPing) doCheck(tags []string, duration time.Duration, rounds int)
h.Settings.Destination,
h.Settings.Timeout,
handler,
h.Settings.ExpectedResponseCode,
)
for i := 0; i < rounds; i++ {
delay := time.Duration(0)

View File

@@ -5,26 +5,30 @@ import (
"net/http"
"time"
"github.com/xtls/xray-core/common/errors"
"github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/transport/internet/tagged"
)
type pingClient struct {
destination string
httpClient *http.Client
destination string
httpClient *http.Client
expectedResponseCode []int32
}
func newPingClient(ctx context.Context, destination string, timeout time.Duration, handler string) *pingClient {
func newPingClient(ctx context.Context, destination string, timeout time.Duration, handler string, expectedResponseCode []int32) *pingClient {
return &pingClient{
destination: destination,
httpClient: newHTTPClient(ctx, handler, timeout),
destination: destination,
httpClient: newHTTPClient(ctx, handler, timeout),
expectedResponseCode: expectedResponseCode,
}
}
func newDirectPingClient(destination string, timeout time.Duration) *pingClient {
return &pingClient{
destination: destination,
httpClient: &http.Client{Timeout: timeout},
destination: destination,
httpClient: &http.Client{Timeout: timeout},
expectedResponseCode: []int32{},
}
}
@@ -63,6 +67,18 @@ func (s *pingClient) MeasureDelay() (time.Duration, error) {
if err != nil {
return rttFailed, err
}
if len(s.expectedResponseCode) > 0 {
found := false
for _, c := range s.expectedResponseCode {
if c == int32(resp.StatusCode) {
found = true
break
}
}
if !found {
return rttFailed, errors.New("Unexpected response code: ", resp.StatusCode, " expected: ", s.expectedResponseCode)
}
}
// don't wait for body
resp.Body.Close()
return time.Since(start), nil

View File

@@ -16,6 +16,7 @@ func TestFileLogger(t *testing.T) {
common.Must(err)
path := f.Name()
common.Must(f.Close())
defer os.Remove(path)
creator, err := CreateFileLogWriter(path)
common.Must(err)

View File

@@ -19,7 +19,7 @@ import (
var (
Version_x byte = 24
Version_y byte = 11
Version_z byte = 11
Version_z byte = 21
)
var (

4
go.mod
View File

@@ -14,7 +14,7 @@ require (
github.com/pires/go-proxyproto v0.8.0
github.com/quic-go/quic-go v0.46.0
github.com/refraction-networking/utls v1.6.7
github.com/sagernet/sing v0.5.0
github.com/sagernet/sing v0.5.1
github.com/sagernet/sing-shadowsocks v0.2.7
github.com/seiflotfy/cuckoofilter v0.0.0-20240715131351-a2f2c23f1771
github.com/stretchr/testify v1.9.0
@@ -28,7 +28,7 @@ require (
golang.org/x/sys v0.27.0
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173
google.golang.org/grpc v1.67.1
google.golang.org/protobuf v1.35.1
google.golang.org/protobuf v1.35.2
gvisor.dev/gvisor v0.0.0-20231202080848-1f7806d17489
h12.io/socks v1.0.3
lukechampine.com/blake3 v1.3.0

8
go.sum
View File

@@ -54,8 +54,8 @@ github.com/refraction-networking/utls v1.6.7 h1:zVJ7sP1dJx/WtVuITug3qYUq034cDq9B
github.com/refraction-networking/utls v1.6.7/go.mod h1:BC3O4vQzye5hqpmDTWUqi4P5DDhzJfkV1tdqtawQIH0=
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg=
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3/go.mod h1:HgjTstvQsPGkxUsCd2KWxErBblirPizecHcpD3ffK+s=
github.com/sagernet/sing v0.5.0 h1:soo2wVwLcieKWWKIksFNK6CCAojUgAppqQVwyRYGkEM=
github.com/sagernet/sing v0.5.0/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
github.com/sagernet/sing v0.5.1 h1:mhL/MZVq0TjuvHcpYcFtmSD1BFOxZ/+8ofbNZcg1k1Y=
github.com/sagernet/sing v0.5.1/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
github.com/sagernet/sing-shadowsocks v0.2.7 h1:zaopR1tbHEw5Nk6FAkM05wCslV6ahVegEZaKMv9ipx8=
github.com/sagernet/sing-shadowsocks v0.2.7/go.mod h1:0rIKJZBR65Qi0zwdKezt4s57y/Tl1ofkaq6NlkzVuyE=
github.com/seiflotfy/cuckoofilter v0.0.0-20240715131351-a2f2c23f1771 h1:emzAzMZ1L9iaKCTxdy3Em8Wv4ChIAGnfiz18Cda70g4=
@@ -129,8 +129,8 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:
google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E=
google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA=
google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA=
google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io=
google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

View File

@@ -42,6 +42,10 @@ type Address struct {
net.Address
}
func (v Address) MarshalJSON() ([]byte, error) {
return json.Marshal(v.Address.String())
}
func (v *Address) UnmarshalJSON(data []byte) error {
var rawStr string
if err := json.Unmarshal(data, &rawStr); err != nil {

View File

@@ -2,57 +2,15 @@ package conf_test
import (
"encoding/json"
"os"
"path/filepath"
"testing"
"github.com/xtls/xray-core/app/dns"
"github.com/xtls/xray-core/app/router"
"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/common/platform"
"github.com/xtls/xray-core/common/platform/filesystem"
. "github.com/xtls/xray-core/infra/conf"
"google.golang.org/protobuf/proto"
)
func init() {
wd, err := os.Getwd()
common.Must(err)
if _, err := os.Stat(platform.GetAssetLocation("geoip.dat")); err != nil && os.IsNotExist(err) {
common.Must(filesystem.CopyFile(platform.GetAssetLocation("geoip.dat"), filepath.Join(wd, "..", "..", "resources", "geoip.dat")))
}
geositeFilePath := filepath.Join(wd, "geosite.dat")
os.Setenv("xray.location.asset", wd)
geositeFile, err := os.OpenFile(geositeFilePath, os.O_CREATE|os.O_WRONLY, 0o600)
common.Must(err)
defer geositeFile.Close()
list := &router.GeoSiteList{
Entry: []*router.GeoSite{
{
CountryCode: "TEST",
Domain: []*router.Domain{
{Type: router.Domain_Full, Value: "example.com"},
},
},
},
}
listBytes, err := proto.Marshal(list)
common.Must(err)
common.Must2(geositeFile.Write(listBytes))
}
func TestDNSConfigParsing(t *testing.T) {
geositePath := platform.GetAssetLocation("geosite.dat")
defer func() {
os.Remove(geositePath)
os.Unsetenv("xray.location.asset")
}()
parserCreator := func() func(string) (proto.Message, error) {
return func(s string) (proto.Message, error) {
config := new(DNSConfig)

View File

@@ -46,20 +46,22 @@ type strategyLeastLoadConfig struct {
// healthCheckSettings holds settings for health Checker
type healthCheckSettings struct {
Destination string `json:"destination"`
Connectivity string `json:"connectivity"`
Interval duration.Duration `json:"interval"`
SamplingCount int `json:"sampling"`
Timeout duration.Duration `json:"timeout"`
Destination string `json:"destination"`
Connectivity string `json:"connectivity"`
Interval duration.Duration `json:"interval"`
SamplingCount int `json:"sampling"`
Timeout duration.Duration `json:"timeout"`
ExpectedResponseCode []int32 `json:"expectedResponseCode"`
}
func (h healthCheckSettings) Build() (proto.Message, error) {
return &burst.HealthPingConfig{
Destination: h.Destination,
Connectivity: h.Connectivity,
Interval: int64(h.Interval),
Timeout: int64(h.Timeout),
SamplingCount: int32(h.SamplingCount),
Destination: h.Destination,
Connectivity: h.Connectivity,
Interval: int64(h.Interval),
Timeout: int64(h.Timeout),
SamplingCount: int32(h.SamplingCount),
ExpectedResponseCode: h.ExpectedResponseCode,
}, nil
}

View File

@@ -2,6 +2,7 @@ package conf_test
import (
"encoding/json"
"fmt"
"os"
"path/filepath"
"testing"
@@ -18,21 +19,44 @@ import (
"google.golang.org/protobuf/proto"
)
func init() {
wd, err := os.Getwd()
common.Must(err)
if _, err := os.Stat(platform.GetAssetLocation("geoip.dat")); err != nil && os.IsNotExist(err) {
common.Must(filesystem.CopyFile(platform.GetAssetLocation("geoip.dat"), filepath.Join(wd, "..", "..", "resources", "geoip.dat")))
func getAssetPath(file string) (string, error) {
path := platform.GetAssetLocation(file)
_, err := os.Stat(path)
if os.IsNotExist(err) {
path := filepath.Join("..", "..", "resources", file)
_, err := os.Stat(path)
if os.IsNotExist(err) {
return "", fmt.Errorf("can't find %s in standard asset locations or {project_root}/resources", file)
}
if err != nil {
return "", fmt.Errorf("can't stat %s: %v", path, err)
}
return path, nil
}
if err != nil {
return "", fmt.Errorf("can't stat %s: %v", path, err)
}
os.Setenv("xray.location.asset", wd)
return path, nil
}
func TestToCidrList(t *testing.T) {
t.Log(os.Getenv("xray.location.asset"))
tempDir, err := os.MkdirTemp("", "test-")
if err != nil {
t.Fatalf("can't create temp dir: %v", err)
}
defer os.RemoveAll(tempDir)
common.Must(filesystem.CopyFile(platform.GetAssetLocation("geoiptestrouter.dat"), "geoip.dat"))
geoipPath, err := getAssetPath("geoip.dat")
if err != nil {
t.Fatal(err)
}
common.Must(filesystem.CopyFile(filepath.Join(tempDir, "geoip.dat"), geoipPath))
common.Must(filesystem.CopyFile(filepath.Join(tempDir, "geoiptestrouter.dat"), geoipPath))
os.Setenv("xray.location.asset", tempDir)
defer os.Unsetenv("xray.location.asset")
ips := StringList([]string{
"geoip:us",
@@ -44,7 +68,7 @@ func TestToCidrList(t *testing.T) {
"ext-ip:geoiptestrouter.dat:!ca",
})
_, err := ToCidrList(ips)
_, err = ToCidrList(ips)
if err != nil {
t.Fatalf("Failed to parse geoip list, got %s", err)
}

View File

@@ -235,6 +235,7 @@ type SplitHTTPConfig struct {
DownloadSettings *StreamConfig `json:"downloadSettings"`
Mode string `json:"mode"`
Extra json.RawMessage `json:"extra"`
NoGRPCHeader bool `json:"noGRPCHeader"`
}
type Xmux struct {
@@ -322,6 +323,7 @@ func (c *SplitHTTPConfig) Build() (proto.Message, error) {
XPaddingBytes: splithttpNewRandRangeConfig(c.XPaddingBytes),
Xmux: &muxProtobuf,
Mode: c.Mode,
NoGRPCHeader: c.NoGRPCHeader,
}
var err error
if c.DownloadSettings != nil {

View File

@@ -81,7 +81,7 @@ func (v *TimedUserValidator) GetAEAD(userHash []byte) (*protocol.MemoryUser, boo
if err != nil {
return nil, false, err
}
return userd.(*protocol.MemoryUser), true, err
return userd.(*protocol.MemoryUser), true, nil
}
func (v *TimedUserValidator) Remove(email string) bool {

View File

@@ -144,15 +144,20 @@ func (s *Server) forwardConnection(dest net.Destination, conn net.Conn) {
Reason: "",
})
if s.info.inboundTag != nil {
ctx = session.ContextWithInbound(ctx, s.info.inboundTag)
}
if s.info.outboundTag != nil {
ctx = session.ContextWithOutbounds(ctx, []*session.Outbound{s.info.outboundTag})
}
if s.info.contentTag != nil {
ctx = session.ContextWithContent(ctx, s.info.contentTag)
}
// what's this?
// Session information should not be shared between different connections
// why reuse them in server level? This will cause incorrect destoverride and unexpected routing behavior.
// Disable it temporarily. Maybe s.info should be removed.
// if s.info.inboundTag != nil {
// ctx = session.ContextWithInbound(ctx, s.info.inboundTag)
// }
// if s.info.outboundTag != nil {
// ctx = session.ContextWithOutbounds(ctx, []*session.Outbound{s.info.outboundTag})
// }
// if s.info.contentTag != nil {
// ctx = session.ContextWithContent(ctx, s.info.contentTag)
// }
link, err := s.info.dispatcher.Dispatch(ctx, dest)
if err != nil {

View File

@@ -4,16 +4,18 @@ package wireguard
import (
"context"
"errors"
goerrors "errors"
"fmt"
"net"
"net/netip"
"os"
"sync"
"golang.org/x/sys/unix"
"github.com/sagernet/sing/common/control"
"github.com/vishvananda/netlink"
"github.com/xtls/xray-core/common/errors"
wgtun "golang.zx2c4.com/wireguard/tun"
)
@@ -27,6 +29,23 @@ type deviceNet struct {
rules []*netlink.Rule
}
var (
tableIndex int = 10230
mu sync.Mutex
)
func allocateIPv6TableIndex() int {
mu.Lock()
defer mu.Unlock()
if tableIndex > 10230 {
errors.LogInfo(context.Background(), "allocate new ipv6 table index: ", tableIndex)
}
currentIndex := tableIndex
tableIndex++
return currentIndex
}
func newDeviceNet(interfaceName string) *deviceNet {
var dialer net.Dialer
bindControl := control.BindToInterface(control.NewDefaultInterfaceFinder(), interfaceName, -1)
@@ -68,7 +87,7 @@ func (d *deviceNet) Close() (err error) {
if len(errs) == 0 {
return nil
}
return errors.Join(errs...)
return goerrors.Join(errs...)
}
func createKernelTun(localAddresses []netip.Addr, mtu int, handler promiscuousModeHandler) (t Tunnel, err error) {
@@ -138,7 +157,7 @@ func createKernelTun(localAddresses []netip.Addr, mtu int, handler promiscuousMo
}
}
ipv6TableIndex := 1023
ipv6TableIndex := allocateIPv6TableIndex()
if v6 != nil {
r := &netlink.Route{Table: ipv6TableIndex}
for {

View File

@@ -8,7 +8,7 @@ import (
func (c *Config) getHosts() []string {
if len(c.Host) == 0 {
return []string{"www.example.com"}
return []string{""}
}
return c.Host
}

View File

@@ -215,9 +215,16 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me
}
}
Host := httpSettings.getRandomHost()
if Host == "" && net.ParseAddress(dest.NetAddr()).Family().IsDomain() {
Host = dest.Address.String()
} else if Host == "" {
Host = "www.example.com"
}
request := &http.Request{
Method: httpMethod,
Host: httpSettings.getRandomHost(),
Host: Host,
Body: breader,
URL: &url.URL{
Scheme: "https",

View File

@@ -255,7 +255,7 @@ func UClient(c net.Conn, config *Config, ctx context.Context, dest net.Destinati
// Do not close the connection
}()
time.Sleep(time.Duration(randBetween(config.SpiderY[8], config.SpiderY[9])) * time.Millisecond) // return
return nil, errors.New("REALITY: processed invalid connection")
return nil, errors.New("REALITY: processed invalid connection").AtWarning()
}
return uConn, nil
}

View File

@@ -46,6 +46,9 @@ func (c *DefaultDialerClient) OpenUpload(ctx context.Context, baseURL string) io
reader, writer := io.Pipe()
req, _ := http.NewRequestWithContext(ctx, "POST", baseURL, reader)
req.Header = c.transportConfig.GetRequestHeader()
if !c.transportConfig.NoGRPCHeader {
req.Header.Set("Content-Type", "application/grpc")
}
go c.client.Do(req)
return writer
}

View File

@@ -37,6 +37,7 @@ type Config struct {
Xmux *Multiplexing `protobuf:"bytes,9,opt,name=xmux,proto3" json:"xmux,omitempty"`
DownloadSettings *internet.StreamConfig `protobuf:"bytes,10,opt,name=downloadSettings,proto3" json:"downloadSettings,omitempty"`
Mode string `protobuf:"bytes,11,opt,name=mode,proto3" json:"mode,omitempty"`
NoGRPCHeader bool `protobuf:"varint,12,opt,name=noGRPCHeader,proto3" json:"noGRPCHeader,omitempty"`
}
func (x *Config) Reset() {
@@ -146,6 +147,13 @@ func (x *Config) GetMode() string {
return ""
}
func (x *Config) GetNoGRPCHeader() bool {
if x != nil {
return x.NoGRPCHeader
}
return false
}
type RandRangeConfig struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -278,7 +286,7 @@ var file_transport_internet_splithttp_config_proto_rawDesc = []byte{
0x72, 0x6e, 0x65, 0x74, 0x2e, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x68, 0x74, 0x74, 0x70, 0x1a, 0x1f,
0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e,
0x65, 0x74, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22,
0x96, 0x06, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x6f,
0xba, 0x06, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x6f,
0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x12, 0x12,
0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61,
0x74, 0x68, 0x12, 0x4d, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x03, 0x20, 0x03,
@@ -323,47 +331,50 @@ var file_transport_internet_splithttp_config_proto_rawDesc = []byte{
0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61,
0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x10, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61,
0x64, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x6f, 0x64,
0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x1a, 0x39, 0x0a,
0x0b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 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, 0x35, 0x0a, 0x0f, 0x52, 0x61, 0x6e, 0x64,
0x52, 0x61, 0x6e, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x66,
0x72, 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12,
0x0e, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x74, 0x6f, 0x22,
0xfe, 0x02, 0x0a, 0x0c, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x78, 0x69, 0x6e, 0x67,
0x12, 0x5a, 0x0a, 0x0e, 0x6d, 0x61, 0x78, 0x43, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e,
0x63, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e,
0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e,
0x65, 0x74, 0x2e, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x68, 0x74, 0x74, 0x70, 0x2e, 0x52, 0x61, 0x6e,
0x64, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0e, 0x6d, 0x61,
0x78, 0x43, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x5a, 0x0a, 0x0e,
0x6d, 0x61, 0x78, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x74, 0x72, 0x61, 0x6e,
0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x73,
0x70, 0x6c, 0x69, 0x74, 0x68, 0x74, 0x74, 0x70, 0x2e, 0x52, 0x61, 0x6e, 0x64, 0x52, 0x61, 0x6e,
0x67, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0e, 0x6d, 0x61, 0x78, 0x43, 0x6f, 0x6e,
0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x5a, 0x0a, 0x0e, 0x63, 0x4d, 0x61, 0x78,
0x52, 0x65, 0x75, 0x73, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x32, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72,
0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x73, 0x70, 0x6c, 0x69, 0x74,
0x68, 0x74, 0x74, 0x70, 0x2e, 0x52, 0x61, 0x6e, 0x64, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x43, 0x6f,
0x6e, 0x66, 0x69, 0x67, 0x52, 0x0e, 0x63, 0x4d, 0x61, 0x78, 0x52, 0x65, 0x75, 0x73, 0x65, 0x54,
0x69, 0x6d, 0x65, 0x73, 0x12, 0x5a, 0x0a, 0x0e, 0x63, 0x4d, 0x61, 0x78, 0x4c, 0x69, 0x66, 0x65,
0x74, 0x69, 0x6d, 0x65, 0x4d, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x78,
0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x22, 0x0a,
0x0c, 0x6e, 0x6f, 0x47, 0x52, 0x50, 0x43, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x0c, 0x20,
0x01, 0x28, 0x08, 0x52, 0x0c, 0x6e, 0x6f, 0x47, 0x52, 0x50, 0x43, 0x48, 0x65, 0x61, 0x64, 0x65,
0x72, 0x1a, 0x39, 0x0a, 0x0b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 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, 0x35, 0x0a, 0x0f,
0x52, 0x61, 0x6e, 0x64, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12,
0x12, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x66,
0x72, 0x6f, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52,
0x02, 0x74, 0x6f, 0x22, 0xfe, 0x02, 0x0a, 0x0c, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65,
0x78, 0x69, 0x6e, 0x67, 0x12, 0x5a, 0x0a, 0x0e, 0x6d, 0x61, 0x78, 0x43, 0x6f, 0x6e, 0x63, 0x75,
0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x78,
0x72, 0x61, 0x79, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e,
0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x68, 0x74, 0x74, 0x70,
0x2e, 0x52, 0x61, 0x6e, 0x64, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
0x52, 0x0e, 0x63, 0x4d, 0x61, 0x78, 0x4c, 0x69, 0x66, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x4d, 0x73,
0x42, 0x85, 0x01, 0x0a, 0x25, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x74, 0x72,
0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74,
0x2e, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x68, 0x74, 0x74, 0x70, 0x50, 0x01, 0x5a, 0x36, 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, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72,
0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2f, 0x73, 0x70, 0x6c, 0x69, 0x74,
0x68, 0x74, 0x74, 0x70, 0xaa, 0x02, 0x21, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x54, 0x72, 0x61, 0x6e,
0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x53,
0x70, 0x6c, 0x69, 0x74, 0x48, 0x74, 0x74, 0x70, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x52, 0x0e, 0x6d, 0x61, 0x78, 0x43, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79,
0x12, 0x5a, 0x0a, 0x0e, 0x6d, 0x61, 0x78, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f,
0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e,
0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e,
0x65, 0x74, 0x2e, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x68, 0x74, 0x74, 0x70, 0x2e, 0x52, 0x61, 0x6e,
0x64, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0e, 0x6d, 0x61,
0x78, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x5a, 0x0a, 0x0e,
0x63, 0x4d, 0x61, 0x78, 0x52, 0x65, 0x75, 0x73, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x18, 0x03,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x74, 0x72, 0x61, 0x6e,
0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x73,
0x70, 0x6c, 0x69, 0x74, 0x68, 0x74, 0x74, 0x70, 0x2e, 0x52, 0x61, 0x6e, 0x64, 0x52, 0x61, 0x6e,
0x67, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0e, 0x63, 0x4d, 0x61, 0x78, 0x52, 0x65,
0x75, 0x73, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x12, 0x5a, 0x0a, 0x0e, 0x63, 0x4d, 0x61, 0x78,
0x4c, 0x69, 0x66, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x4d, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x32, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72,
0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x73, 0x70, 0x6c, 0x69, 0x74,
0x68, 0x74, 0x74, 0x70, 0x2e, 0x52, 0x61, 0x6e, 0x64, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x43, 0x6f,
0x6e, 0x66, 0x69, 0x67, 0x52, 0x0e, 0x63, 0x4d, 0x61, 0x78, 0x4c, 0x69, 0x66, 0x65, 0x74, 0x69,
0x6d, 0x65, 0x4d, 0x73, 0x42, 0x85, 0x01, 0x0a, 0x25, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61,
0x79, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65,
0x72, 0x6e, 0x65, 0x74, 0x2e, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x68, 0x74, 0x74, 0x70, 0x50, 0x01,
0x5a, 0x36, 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, 0x74, 0x72, 0x61, 0x6e,
0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2f, 0x73,
0x70, 0x6c, 0x69, 0x74, 0x68, 0x74, 0x74, 0x70, 0xaa, 0x02, 0x21, 0x58, 0x72, 0x61, 0x79, 0x2e,
0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e,
0x65, 0x74, 0x2e, 0x53, 0x70, 0x6c, 0x69, 0x74, 0x48, 0x74, 0x74, 0x70, 0x62, 0x06, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x33,
}
var (

View File

@@ -20,6 +20,7 @@ message Config {
Multiplexing xmux = 9;
xray.transport.internet.StreamConfig downloadSettings = 10;
string mode = 11;
bool noGRPCHeader = 12;
}
message RandRangeConfig {

View File

@@ -312,9 +312,13 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me
}
mode := transportConfiguration.Mode
if mode == "auto" && realityConfig != nil {
mode = "stream-up"
if mode == "auto" {
mode = "packet-up"
if (tlsConfig != nil && len(tlsConfig.NextProtocol) != 1) || realityConfig != nil {
mode = "stream-up"
}
}
errors.LogInfo(ctx, "XHTTP is using mode: "+mode)
if mode == "stream-up" {
conn.writer = httpClient.OpenUpload(ctx, requestURL.String())
return stat.Connection(&conn), nil
@@ -324,7 +328,8 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me
// WithSizeLimit(0) will still allow single bytes to pass, and a lot of
// code relies on this behavior. Subtract 1 so that together with
// uploadWriter wrapper, exact size limits can be enforced
uploadPipeReader, uploadPipeWriter := pipe.New(pipe.WithSizeLimit(maxUploadSize - 1))
// uploadPipeReader, uploadPipeWriter := pipe.New(pipe.WithSizeLimit(maxUploadSize - 1))
uploadPipeReader, uploadPipeWriter := pipe.New(pipe.WithSizeLimit(maxUploadSize - buf.Size))
conn.writer = uploadWriter{
uploadPipeWriter,
@@ -400,10 +405,12 @@ type uploadWriter struct {
}
func (w uploadWriter) Write(b []byte) (int, error) {
capacity := int(w.maxLen - w.Len())
if capacity > 0 && capacity < len(b) {
b = b[:capacity]
}
/*
capacity := int(w.maxLen - w.Len())
if capacity > 0 && capacity < len(b) {
b = b[:capacity]
}
*/
buffer := buf.New()
n, err := buffer.Write(b)

View File

@@ -424,8 +424,8 @@ func Test_maxUpload(t *testing.T) {
ProtocolSettings: &Config{
Path: "/sh",
ScMaxEachPostBytes: &RandRangeConfig{
From: 100,
To: 100,
From: 10000,
To: 10000,
},
},
}
@@ -434,7 +434,7 @@ func Test_maxUpload(t *testing.T) {
listen, err := ListenSH(context.Background(), net.LocalHostIP, listenPort, streamSettings, func(conn stat.Connection) {
go func(c stat.Connection) {
defer c.Close()
var b [1024]byte
var b [10240]byte
c.SetReadDeadline(time.Now().Add(2 * time.Second))
n, err := c.Read(b[:])
if err != nil {
@@ -452,11 +452,11 @@ func Test_maxUpload(t *testing.T) {
conn, err := Dial(ctx, net.TCPDestination(net.DomainAddress("localhost"), listenPort), streamSettings)
// send a slightly too large upload
var upload [101]byte
var upload [10001]byte
_, err = conn.Write(upload[:])
common.Must(err)
var b [1024]byte
var b [10240]byte
n, _ := io.ReadFull(conn, b[:])
fmt.Println("string is", n)
if string(b[:n]) != "Response" {
@@ -464,7 +464,7 @@ func Test_maxUpload(t *testing.T) {
}
common.Must(conn.Close())
if uploadSize > 100 || uploadSize == 0 {
if uploadSize > 10000 || uploadSize == 0 {
t.Error("incorrect upload size: ", uploadSize)
}

View File

@@ -51,5 +51,5 @@ func (c *Config) getCertPool() (*x509.CertPool, error) {
return nil, errors.New("append cert to root").AtWarning().Base(err)
}
}
return pool, err
return pool, nil
}