Compare commits

..
Author SHA1 Message Date
Fangliding 86453821f3 Pinning ca must have serverName 2026-07-11 03:45:01 +08:00
22 changed files with 97 additions and 301 deletions
-1
View File
@@ -37,7 +37,6 @@ RUN echo '{}' >/tmp/usr/local/etc/xray/08_fakedns.json
RUN echo '{}' >/tmp/usr/local/etc/xray/09_metrics.json
RUN echo '{}' >/tmp/usr/local/etc/xray/10_observatory.json
RUN echo '{}' >/tmp/usr/local/etc/xray/11_geodata.json
RUN echo '{}' >/tmp/usr/local/etc/xray/12_env.json
RUN echo '{}' >/tmp/usr/local/etc/xray/99_version.json
# Create log files
-1
View File
@@ -37,7 +37,6 @@ RUN echo '{}' >/tmp/usr/local/etc/xray/08_fakedns.json
RUN echo '{}' >/tmp/usr/local/etc/xray/09_metrics.json
RUN echo '{}' >/tmp/usr/local/etc/xray/10_observatory.json
RUN echo '{}' >/tmp/usr/local/etc/xray/11_geodata.json
RUN echo '{}' >/tmp/usr/local/etc/xray/12_env.json
RUN echo '{}' >/tmp/usr/local/etc/xray/99_version.json
# Create log files
+1 -1
View File
@@ -122,7 +122,7 @@ func NewReader(reader io.Reader) Reader {
}
_, isFile := reader.(*os.File)
if !isFile && useReadV() {
if !isFile && useReadv {
if sc, ok := reader.(syscall.Conn); ok {
rawConn, err := sc.SyscallConn()
if err != nil {
+7 -19
View File
@@ -5,7 +5,6 @@ package buf
import (
"io"
"sync/atomic"
"syscall"
"github.com/xtls/xray-core/common/platform"
@@ -144,24 +143,13 @@ func (r *ReadVReader) ReadMultiBuffer() (MultiBuffer, error) {
return mb, nil
}
var useReadv atomic.Bool
func useReadV() bool {
return useReadv.Load()
}
func reloadEnvSettings() error {
const defaultFlagValue = "NOT_DEFINED_AT_ALL"
value := platform.NewEnvFlag(platform.UseReadV).GetValue(func() string { return defaultFlagValue })
enabled := false
switch value {
case defaultFlagValue, "auto", "enable":
enabled = true
}
useReadv.Store(enabled)
return nil
}
var useReadv bool
func init() {
platform.RegisterEnvReload(reloadEnvSettings)
const defaultFlagValue = "NOT_DEFINED_AT_ALL"
value := platform.NewEnvFlag(platform.UseReadV).GetValue(func() string { return defaultFlagValue })
switch value {
case defaultFlagValue, "auto", "enable":
useReadv = true
}
}
+1 -3
View File
@@ -10,9 +10,7 @@ import (
"github.com/xtls/xray-core/features/stats"
)
func useReadV() bool {
return false
}
const useReadv = false
func NewReadVReader(reader io.Reader, rawConn syscall.RawConn, counter stats.Counter) Reader {
panic("not implemented")
-40
View File
@@ -1,40 +0,0 @@
package platform
import (
"errors"
"sync"
)
var envReloadRegistry = struct {
sync.RWMutex
handlers []func() error
}{}
// RegisterEnvReload registers an environment reload handler and runs it once
// immediately so package defaults keep the same behavior as init-time reads.
func RegisterEnvReload(handler func() error) {
if handler == nil {
return
}
envReloadRegistry.Lock()
envReloadRegistry.handlers = append(envReloadRegistry.handlers, handler)
envReloadRegistry.Unlock()
if err := handler(); err != nil {
panic(err)
}
}
// ReloadEnvSettings refreshes all registered environment-backed package state.
func ReloadEnvSettings() error {
envReloadRegistry.RLock()
handlers := append([]func() error{}, envReloadRegistry.handlers...)
envReloadRegistry.RUnlock()
var errs []error
for _, handler := range handlers {
if err := handler(); err != nil {
errs = append(errs, err)
}
}
return errors.Join(errs...)
}
+19 -33
View File
@@ -8,7 +8,7 @@ import (
"io"
"strconv"
"strings"
"sync/atomic"
"time"
"github.com/xtls/xray-core/common/buf"
"github.com/xtls/xray-core/common/errors"
@@ -27,39 +27,25 @@ var AddrParser = protocol.NewAddressParser(
)
var (
Show atomic.Bool
baseKey atomic.Value
Show bool
BaseKey []byte
)
func reloadEnvSettings() error {
Show.Store(strings.ToLower(platform.NewEnvFlag(platform.XUDPLog).GetValue(func() string { return "" })) == "true")
raw := platform.NewEnvFlag(platform.XUDPBaseKey).GetValue(func() string { return "" })
if raw == "" {
ensureBaseKey()
return nil
}
key, _ := base64.RawURLEncoding.DecodeString(raw)
if len(key) != 32 {
return errors.New(platform.XUDPBaseKey + ": invalid value (BaseKey must be 32 bytes): " + raw + " len " + strconv.Itoa(len(key)))
}
baseKey.Store(append([]byte(nil), key...))
return nil
}
func ensureBaseKey() []byte {
if key := baseKey.Load(); key != nil {
return key.([]byte)
}
key := make([]byte, 32)
if _, err := rand.Read(key); err != nil {
panic(err)
}
baseKey.Store(key)
return key
}
func init() {
platform.RegisterEnvReload(reloadEnvSettings)
if strings.ToLower(platform.NewEnvFlag(platform.XUDPLog).GetValue(func() string { return "" })) == "true" {
Show = true
}
BaseKey = make([]byte, 32)
rand.Read(BaseKey)
go func() {
time.Sleep(100 * time.Millisecond) // this is not nice, but need to give some time for Android to setup ENV
if raw := platform.NewEnvFlag(platform.XUDPBaseKey).GetValue(func() string { return "" }); raw != "" {
if BaseKey, _ = base64.RawURLEncoding.DecodeString(raw); len(BaseKey) == 32 {
return
}
panic(platform.XUDPBaseKey + ": invalid value (BaseKey must be 32 bytes): " + raw + " len " + strconv.Itoa(len(BaseKey)))
}
}()
}
func GetGlobalID(ctx context.Context) (globalID [8]byte) {
@@ -68,10 +54,10 @@ func GetGlobalID(ctx context.Context) (globalID [8]byte) {
}
if inbound := session.InboundFromContext(ctx); inbound != nil && inbound.Source.Network == net.Network_UDP &&
(inbound.Name == "dokodemo-door" || inbound.Name == "socks" || inbound.Name == "shadowsocks" || inbound.Name == "tun") {
h := blake3.New(8, ensureBaseKey())
h := blake3.New(8, BaseKey)
h.Write([]byte(inbound.Source.String()))
copy(globalID[:], h.Sum(nil))
if Show.Load() {
if Show {
errors.LogInfo(ctx, fmt.Sprintf("XUDP inbound.Source.String(): %v\tglobalID: %v\n", inbound.Source.String(), globalID))
}
}
-3
View File
@@ -187,9 +187,6 @@ func NewWithContext(ctx context.Context, config *Config) (*Instance, error) {
}
func initInstanceWithConfig(config *Config, server *Instance) (bool, error) {
if err := platform.ReloadEnvSettings(); err != nil {
return true, errors.New("failed to reload environment settings").Base(err)
}
server.ctx = context.WithValue(server.ctx, "cone",
platform.NewEnvFlag(platform.UseCone).GetValue(func() string { return "" }) != "true")
+8 -18
View File
@@ -3,7 +3,6 @@ package policy
import (
"context"
"runtime"
"sync/atomic"
"time"
"github.com/xtls/xray-core/common/platform"
@@ -83,41 +82,32 @@ func ManagerType() interface{} {
return (*Manager)(nil)
}
var defaultBufferSize atomic.Int32
var defaultBufferSize int32
func reloadEnvSettings() error {
defaultBufferSize.Store(readDefaultBufferSize())
return nil
}
func readDefaultBufferSize() int32 {
func init() {
const defaultValue = -17
size := platform.NewEnvFlag(platform.BufferSize).GetValueAsInt(defaultValue)
switch size {
case 0:
return -1 // For pipe to use unlimited size
defaultBufferSize = -1 // For pipe to use unlimited size
case defaultValue: // Env flag not defined. Use default values per CPU-arch.
switch runtime.GOARCH {
case "arm", "mips", "mipsle":
return 0
defaultBufferSize = 0
case "arm64", "mips64", "mips64le":
return 4 * 1024 // 4k cache for low-end devices
defaultBufferSize = 4 * 1024 // 4k cache for low-end devices
default:
return 512 * 1024
defaultBufferSize = 512 * 1024
}
default:
return int32(size) * 1024 * 1024
defaultBufferSize = int32(size) * 1024 * 1024
}
}
func init() {
platform.RegisterEnvReload(reloadEnvSettings)
}
func defaultBufferPolicy() Buffer {
return Buffer{
PerConnection: defaultBufferSize.Load(),
PerConnection: defaultBufferSize,
}
}
+8 -8
View File
@@ -14,7 +14,7 @@ require (
github.com/miekg/dns v1.1.72
github.com/pelletier/go-toml v1.9.5
github.com/pion/stun/v3 v3.1.6
github.com/pires/go-proxyproto v0.15.0
github.com/pires/go-proxyproto v0.14.0
github.com/refraction-networking/utls v1.8.3-0.20260301010127-aa6edf4b11af
github.com/robfig/cron/v3 v3.0.1
github.com/sagernet/sing v0.5.1
@@ -23,11 +23,11 @@ require (
github.com/vishvananda/netlink v1.3.1
github.com/xtls/reality v0.0.0-20260322125925-9234c772ba8f
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba
golang.org/x/crypto v0.54.0
golang.org/x/crypto v0.53.0
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842
golang.org/x/net v0.57.0
golang.org/x/sync v0.22.0
golang.org/x/sys v0.47.0
golang.org/x/net v0.56.0
golang.org/x/sync v0.21.0
golang.org/x/sys v0.46.0
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2
golang.zx2c4.com/wireguard v0.0.0-20250521234502-f333402bd9cb
golang.zx2c4.com/wireguard/windows v1.0.1
@@ -52,10 +52,10 @@ require (
github.com/quic-go/qpack v0.6.0 // indirect
github.com/vishvananda/netns v0.0.5 // indirect
github.com/wlynxg/anet v0.0.5 // indirect
golang.org/x/mod v0.37.0 // indirect
golang.org/x/text v0.40.0 // indirect
golang.org/x/mod v0.36.0 // indirect
golang.org/x/text v0.38.0 // indirect
golang.org/x/time v0.14.0 // indirect
golang.org/x/tools v0.47.0 // indirect
golang.org/x/tools v0.45.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
+16 -16
View File
@@ -53,8 +53,8 @@ github.com/pion/stun/v3 v3.1.6 h1:WnhsD0eHCiwCfKNkVx0VJJwr2Y3eV4Ueih3KJ+dfZy8=
github.com/pion/stun/v3 v3.1.6/go.mod h1:zRUghXSQU32Lx5orJsz3uYMkIihweXb3mu5gIns02fs=
github.com/pion/transport/v4 v4.0.2 h1:ifYlPqNwsy6aKQ9y8yzxXlHae5431ZrH2avkD/Rn6Tk=
github.com/pion/transport/v4 v4.0.2/go.mod h1:06hFI+jCFcok2X2MekVufNZ/uzNZXivGBPfviSVcjgM=
github.com/pires/go-proxyproto v0.15.0 h1:dTshmNbFm/D+0+sbrxUuddPOZ5Y0B7c5NhtsBkm6LqI=
github.com/pires/go-proxyproto v0.15.0/go.mod h1:OXsCrKwrK2tXS9YrI5tkHx5xaQlO8FH3lFW76orFh24=
github.com/pires/go-proxyproto v0.14.0 h1:2vIGIfVG8eVRsKF0xukEoeT5RWhDXxBU0uv6smLOKdI=
github.com/pires/go-proxyproto v0.14.0/go.mod h1:OXsCrKwrK2tXS9YrI5tkHx5xaQlO8FH3lFW76orFh24=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8=
@@ -98,22 +98,22 @@ go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBs
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.54.0 h1:YLIA59K4fiNzHzjnZt2tUJQjQtUWfWbeHBqKtk3eScw=
golang.org/x/crypto v0.54.0/go.mod h1:KWL8ny2AZdGR2cWmzeHrp2azQPGogOv+HeQaVEXC2dk=
golang.org/x/crypto v0.53.0 h1:QZ4Muo8THX6CizN2vPPd5fBGHyogrdK9fG4wLPFUsto=
golang.org/x/crypto v0.53.0/go.mod h1:DNLU434OwVakk9PzuwV8w62mAJpRJL3vsgcfp4Qnsio=
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM=
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc=
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/mod v0.37.0 h1:vF1DjpVEshcIqoEaauuHebaLk1O1forxjxBaVn884JQ=
golang.org/x/mod v0.37.0/go.mod h1:m8S8VeM9r4dzDwjrKO0a1sZP3YjeMamRRlD+fmR2Q/0=
golang.org/x/mod v0.36.0 h1:JJjpVx6myfUsUdAzZuOSTTmRE0PfZeNWzzvKrP7amb4=
golang.org/x/mod v0.36.0/go.mod h1:moc6ELqsWcOw5Ef3xVprK5ul/MvtVvkIXLziUOICjUQ=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.57.0 h1:K5+3DljvIuDG9/Jv9rvyMywYNFCQ9RSUY6OOTTkT+tE=
golang.org/x/net v0.57.0/go.mod h1:KpXc8iv+r3XplLAG/f7Jsf9RPszJzdR0f58q9vGOuEU=
golang.org/x/net v0.56.0 h1:Rw8j/hFzGvJUZwNBXnAtf5sVDVt+65SK2C7IxCxZt5o=
golang.org/x/net v0.56.0/go.mod h1:D3Ku6r+V6JROoZK144D2XfMHFcMq/0zSfLelVTCFKec=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek=
golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM=
golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -121,21 +121,21 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs=
golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw=
golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.40.0 h1:Ub2Z6/xjgF1WrYQz2nuITOEegKFtiIy+rieRJ5lHZKs=
golang.org/x/text v0.40.0/go.mod h1:hpnzDAfGV753zIKo+wk3u1bVKCGPbrnF7+7LBF/UHVY=
golang.org/x/text v0.38.0 h1:sXmwo9DwP3OK9EZ7PqAdaooSGozfl/3a6/xJcbzPRhE=
golang.org/x/text v0.38.0/go.mod h1:YXZt3QhHUKYT53r2lLKFIVi6Ao1jdzrTR/KQ09qyxF4=
golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
golang.org/x/tools v0.47.0 h1:7Kn5x/d1svx/PzryTsqeoZN4TZwqeH5pGWjefhLi/1Q=
golang.org/x/tools v0.47.0/go.mod h1:dFHnyTvFWY212G+h7ZY4Vsp/K3U4/7W9TyVaAul8uCA=
golang.org/x/tools v0.45.0 h1:18qN3FAooORvApf5XjCXgsuayZOEtXf6JK18I3+ONa8=
golang.org/x/tools v0.45.0/go.mod h1:LuUGqqaXcXMEFEruIVJVm5mgDD8vww/z/SR1gQ4uE/0=
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-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-59
View File
@@ -1,59 +0,0 @@
package conf
import (
"encoding/json"
"os"
"testing"
)
func TestRootEnvAppliesArbitraryValues(t *testing.T) {
const (
valueKey = "XRAY_TEST_CONFIG_ENV"
emptyKey = "XRAY_TEST_CONFIG_EMPTY"
)
t.Setenv(valueKey, "before")
t.Setenv(emptyKey, "before")
config := new(Config)
if err := json.Unmarshal([]byte(`{
"env": {
"XRAY_TEST_CONFIG_ENV": "configured",
"XRAY_TEST_CONFIG_EMPTY": ""
}
}`), config); err != nil {
t.Fatal(err)
}
if _, err := config.Build(); err != nil {
t.Fatal(err)
}
if got := os.Getenv(valueKey); got != "configured" {
t.Fatalf("env %q = %q, want %q", valueKey, got, "configured")
}
if got := os.Getenv(emptyKey); got != "" {
t.Fatalf("env %q = %q, want empty", emptyKey, got)
}
}
func TestEnvConfigOverride(t *testing.T) {
base := EnvConfig{
"ONE": "one",
"TWO": "old",
}
override := EnvConfig{
"TWO": "new",
"THREE": "three",
}
base.Override(override)
want := map[string]string{
"ONE": "one",
"TWO": "new",
"THREE": "three",
}
for key, value := range want {
if got := base[key]; got != value {
t.Fatalf("env %q = %q, want %q", key, got, value)
}
}
}
-22
View File
@@ -3,7 +3,6 @@ package conf
import (
"context"
"encoding/json"
"os"
"path/filepath"
"strings"
@@ -380,20 +379,11 @@ func (c *StatsConfig) Build() (*stats.Config, error) {
return &stats.Config{}, nil
}
type EnvConfig map[string]string
func (c EnvConfig) Override(o EnvConfig) {
for key, value := range o {
c[key] = value
}
}
type Config struct {
// Deprecated: Global transport config is no longer used
// left for returning error
Transport map[string]json.RawMessage `json:"transport"`
Env EnvConfig `json:"env"`
LogConfig *LogConfig `json:"log"`
RouterConfig *RouterConfig `json:"routing"`
DNSConfig *DNSConfig `json:"dns"`
@@ -449,12 +439,6 @@ func (c *Config) Override(o *Config, fn string) {
if o.Transport != nil {
c.Transport = o.Transport
}
if o.Env != nil {
if c.Env == nil {
c.Env = EnvConfig{}
}
c.Env.Override(o.Env)
}
if o.Policy != nil {
c.Policy = o.Policy
}
@@ -530,12 +514,6 @@ func (c *Config) Override(o *Config, fn string) {
// Build implements Buildable.
func (c *Config) Build() (*core.Config, error) {
for key, value := range c.Env {
if err := os.Setenv(key, value); err != nil {
return nil, errors.New("failed to apply environment configuration").Base(err)
}
}
if err := PostProcessConfigureFile(c); err != nil {
return nil, errors.New("failed to post-process configuration file").Base(err)
}
-4
View File
@@ -36,10 +36,6 @@ The -confdir=dir flag sets a dir with multiple json config
The -format=json flag sets the format of config files.
Default "auto".
The config root env object sets process environment variables after all config
files are parsed. Variables needed to locate or parse config files must be set
in the process environment before Xray starts.
The -test flag tells Xray to test config files only,
without launching the server.
+8 -16
View File
@@ -5,7 +5,6 @@ import (
"crypto/rand"
"io"
"strings"
"sync/atomic"
"time"
"github.com/pires/go-proxyproto"
@@ -32,24 +31,12 @@ import (
)
var (
useSplice atomic.Bool
useSplice bool
allNetworks [8]bool
defaultBlockPrivateRule *FinalRule
defaultBlockAllRule *FinalRule
)
func reloadEnvSettings() error {
const defaultFlagValue = "NOT_DEFINED_AT_ALL"
value := platform.NewEnvFlag(platform.UseFreedomSplice).GetValue(func() string { return defaultFlagValue })
enabled := false
switch value {
case defaultFlagValue, "auto", "enable":
enabled = true
}
useSplice.Store(enabled)
return nil
}
func init() {
common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
h := new(Handler)
@@ -61,7 +48,12 @@ func init() {
return h, nil
}))
platform.RegisterEnvReload(reloadEnvSettings)
const defaultFlagValue = "NOT_DEFINED_AT_ALL"
value := platform.NewEnvFlag(platform.UseFreedomSplice).GetValue(func() string { return defaultFlagValue })
switch value {
case defaultFlagValue, "auto", "enable":
useSplice = true
}
for i := range allNetworks {
allNetworks[i] = true
@@ -430,7 +422,7 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
responseDone := func() error {
defer timer.SetTimeout(plcy.Timeouts.UplinkOnly)
if destination.Network == net.Network_TCP && useSplice.Load() && proxy.IsRAWTransportWithoutSecurity(conn) { // it would be tls conn in special use case of MITM, we need to let link handle traffic
if destination.Network == net.Network_TCP && useSplice && proxy.IsRAWTransportWithoutSecurity(conn) { // it would be tls conn in special use case of MITM, we need to let link handle traffic
var writeConn net.Conn
var inTimer *signal.ActivityTimer
if inbound := session.InboundFromContext(ctx); inbound != nil && inbound.Conn != nil {
+8 -11
View File
@@ -5,7 +5,6 @@ import (
"crypto/hmac"
"crypto/sha256"
"hash/crc64"
"sync/atomic"
"time"
"github.com/xtls/xray-core/common"
@@ -219,17 +218,10 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
return nil
}
var enablePadding atomic.Bool
var enablePadding = false
func shouldEnablePadding(s protocol.SecurityType) bool {
return enablePadding.Load() || s == protocol.SecurityType_AES128_GCM || s == protocol.SecurityType_CHACHA20_POLY1305 || s == protocol.SecurityType_AUTO
}
func reloadEnvSettings() error {
const defaultFlagValue = "NOT_DEFINED_AT_ALL"
paddingValue := platform.NewEnvFlag(platform.UseVmessPadding).GetValue(func() string { return defaultFlagValue })
enablePadding.Store(paddingValue != defaultFlagValue)
return nil
return enablePadding || s == protocol.SecurityType_AES128_GCM || s == protocol.SecurityType_CHACHA20_POLY1305 || s == protocol.SecurityType_AUTO
}
func init() {
@@ -237,5 +229,10 @@ func init() {
return New(ctx, config.(*Config))
}))
platform.RegisterEnvReload(reloadEnvSettings)
const defaultFlagValue = "NOT_DEFINED_AT_ALL"
paddingValue := platform.NewEnvFlag(platform.UseVmessPadding).GetValue(func() string { return defaultFlagValue })
if paddingValue != defaultFlagValue {
enablePadding = true
}
}
+8 -5
View File
@@ -139,7 +139,13 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
ob.Name = "wireguard"
ob.CanSpliceCopy = 3
if err := h.init(ctx); err != nil {
if h.dev == nil {
if err := h.init(ctx); err != nil {
return err
}
}
if err := h.dev.Up(); err != nil {
return err
}
@@ -252,11 +258,8 @@ func (h *Handler) Close() (err error) {
func (h *Handler) init(ctx context.Context) error {
h.mu.Lock()
defer h.mu.Unlock()
if h.tun == nil {
return errors.New("closed")
}
if h.dev != nil {
return h.dev.Up()
return nil
}
resolveFunc := h.resolveLocal
listenFunc := func() (net.PacketConn, error) {
+4 -14
View File
@@ -27,10 +27,9 @@ type task struct {
}
var (
conns chan *websocket.Conn
server *http.Server
currentAddr string
mu sync.Mutex
conns chan *websocket.Conn
server *http.Server
mu sync.Mutex
)
var upgrader = &websocket.Upgrader{
@@ -48,13 +47,8 @@ func Reload() {
mu.Lock()
defer mu.Unlock()
if addr == currentAddr && (addr == "" || server != nil) {
return
}
if server != nil {
server.Close()
server = nil
}
if HasBrowserDialer() {
for len(conns) > 0 {
@@ -66,7 +60,6 @@ func Reload() {
}
conns = nil
}
currentAddr = addr
if addr != "" {
token := uuid.New()
csrfToken := token.String()
@@ -227,8 +220,5 @@ func CheckOK(conn *websocket.Conn) error {
}
func init() {
platform.RegisterEnvReload(func() error {
Reload()
return nil
})
Reload()
}
+1 -4
View File
@@ -136,10 +136,7 @@ func getGrpcClient(ctx context.Context, dest net.Destination, streamSettings *in
}
if tlsConfig != nil {
config := tlsConfig.GetTLSConfig()
if config.ServerName == "" && address.Family().IsDomain() {
config.ServerName = address.Domain()
}
config := tlsConfig.GetTLSConfig(tls.WithDestination(dest))
if fingerprint := tls.GetFingerprint(tlsConfig.Fingerprint); fingerprint != nil {
return tls.UClient(c, config, fingerprint), nil
} else { // Fallback to normal gRPC TLS
+2 -16
View File
@@ -4,10 +4,8 @@ import (
"bufio"
"context"
"crypto/tls"
"io"
"net/http"
"strings"
"time"
"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/errors"
@@ -45,11 +43,7 @@ func (s *server) Handle(conn net.Conn) {
// upgrade execute a fake websocket upgrade process and return the available connection
func (s *server) upgrade(conn net.Conn) (stat.Connection, error) {
// timeout and header limit are the same as websocket
conn.SetReadDeadline(time.Now().Add(time.Second * 4))
defer conn.SetReadDeadline(time.Time{})
connReader := bufio.NewReader(io.LimitReader(conn, 12288))
connReader := bufio.NewReader(conn)
req, err := http.ReadRequest(connReader)
if err != nil {
return nil, err
@@ -100,15 +94,7 @@ func (s *server) keepAccepting() {
for {
conn, err := s.innnerListener.Accept()
if err != nil {
errStr := err.Error()
if strings.Contains(errStr, "closed") {
break
}
errors.LogWarningInner(context.Background(), err, "failed to accept raw connections")
if strings.Contains(errStr, "too many") {
time.Sleep(time.Millisecond * 500)
}
continue
return
}
go s.Handle(conn)
}
+1 -1
View File
@@ -345,7 +345,7 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me
c = &client{
dest: dest,
config: streamSettings.ProtocolSettings.(*Config),
tlsConfig: tlsConfig.GetTLSConfig(),
tlsConfig: tlsConfig.GetTLSConfig(tls.WithDestination(dest)),
socketConfig: streamSettings.SocketSettings,
udpmaskManager: streamSettings.UdpmaskManager,
quicParams: streamSettings.QuicParams,
+5 -6
View File
@@ -331,6 +331,9 @@ func (r *RandCarrier) verifyPeerCert(rawCerts [][]byte, verifiedChains [][]*x509
}
if verifyResult == foundCA { // if found CA, we need to verify here
if len(r.Config.ServerName) == 0 {
return errors.New("Pinning CA needs a valid ServerName")
}
opts := x509.VerifyOptions{
Roots: CAs,
CurrentTime: time.Now(),
@@ -450,13 +453,9 @@ func (c *Config) GetTLSConfig(opts ...Option) *tls.Config {
for _, s := range tls.CipherSuites() {
id[s.Name] = s.ID
}
for _, s := range tls.InsecureCipherSuites() {
id[s.Name] = s.ID
}
for n := range strings.SplitSeq(c.CipherSuites, ":") {
n = strings.TrimSpace(n)
if v, ok := id[n]; ok {
config.CipherSuites = append(config.CipherSuites, v)
if id[n] != 0 {
config.CipherSuites = append(config.CipherSuites, id[n])
}
}
}