mirror of
https://github.com/XTLS/Xray-core.git
synced 2026-07-14 17:08:54 +00:00
Root config: Add env config (#6400)
https://github.com/XTLS/Xray-core/pull/6400#issuecomment-4880198100 https://github.com/XTLS/Xray-core/pull/6400#issuecomment-4916892425 https://github.com/XTLS/Xray-core/pull/6400#issuecomment-4929136670
This commit is contained in:
@@ -37,6 +37,7 @@ 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/09_metrics.json
|
||||||
RUN echo '{}' >/tmp/usr/local/etc/xray/10_observatory.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/11_geodata.json
|
||||||
|
RUN echo '{}' >/tmp/usr/local/etc/xray/12_env.json
|
||||||
RUN echo '{}' >/tmp/usr/local/etc/xray/99_version.json
|
RUN echo '{}' >/tmp/usr/local/etc/xray/99_version.json
|
||||||
|
|
||||||
# Create log files
|
# Create log files
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ 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/09_metrics.json
|
||||||
RUN echo '{}' >/tmp/usr/local/etc/xray/10_observatory.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/11_geodata.json
|
||||||
|
RUN echo '{}' >/tmp/usr/local/etc/xray/12_env.json
|
||||||
RUN echo '{}' >/tmp/usr/local/etc/xray/99_version.json
|
RUN echo '{}' >/tmp/usr/local/etc/xray/99_version.json
|
||||||
|
|
||||||
# Create log files
|
# Create log files
|
||||||
|
|||||||
+1
-1
@@ -122,7 +122,7 @@ func NewReader(reader io.Reader) Reader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_, isFile := reader.(*os.File)
|
_, isFile := reader.(*os.File)
|
||||||
if !isFile && useReadv {
|
if !isFile && useReadV() {
|
||||||
if sc, ok := reader.(syscall.Conn); ok {
|
if sc, ok := reader.(syscall.Conn); ok {
|
||||||
rawConn, err := sc.SyscallConn()
|
rawConn, err := sc.SyscallConn()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ package buf
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
|
"sync/atomic"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/xtls/xray-core/common/platform"
|
"github.com/xtls/xray-core/common/platform"
|
||||||
@@ -143,13 +144,24 @@ func (r *ReadVReader) ReadMultiBuffer() (MultiBuffer, error) {
|
|||||||
return mb, nil
|
return mb, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var useReadv bool
|
var useReadv atomic.Bool
|
||||||
|
|
||||||
func init() {
|
func useReadV() bool {
|
||||||
|
return useReadv.Load()
|
||||||
|
}
|
||||||
|
|
||||||
|
func reloadEnvSettings() error {
|
||||||
const defaultFlagValue = "NOT_DEFINED_AT_ALL"
|
const defaultFlagValue = "NOT_DEFINED_AT_ALL"
|
||||||
value := platform.NewEnvFlag(platform.UseReadV).GetValue(func() string { return defaultFlagValue })
|
value := platform.NewEnvFlag(platform.UseReadV).GetValue(func() string { return defaultFlagValue })
|
||||||
|
enabled := false
|
||||||
switch value {
|
switch value {
|
||||||
case defaultFlagValue, "auto", "enable":
|
case defaultFlagValue, "auto", "enable":
|
||||||
useReadv = true
|
enabled = true
|
||||||
}
|
}
|
||||||
|
useReadv.Store(enabled)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
platform.RegisterEnvReload(reloadEnvSettings)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,9 @@ import (
|
|||||||
"github.com/xtls/xray-core/features/stats"
|
"github.com/xtls/xray-core/features/stats"
|
||||||
)
|
)
|
||||||
|
|
||||||
const useReadv = false
|
func useReadV() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func NewReadVReader(reader io.Reader, rawConn syscall.RawConn, counter stats.Counter) Reader {
|
func NewReadVReader(reader io.Reader, rawConn syscall.RawConn, counter stats.Counter) Reader {
|
||||||
panic("not implemented")
|
panic("not implemented")
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
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...)
|
||||||
|
}
|
||||||
+33
-19
@@ -8,7 +8,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"sync/atomic"
|
||||||
|
|
||||||
"github.com/xtls/xray-core/common/buf"
|
"github.com/xtls/xray-core/common/buf"
|
||||||
"github.com/xtls/xray-core/common/errors"
|
"github.com/xtls/xray-core/common/errors"
|
||||||
@@ -27,25 +27,39 @@ var AddrParser = protocol.NewAddressParser(
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
Show bool
|
Show atomic.Bool
|
||||||
BaseKey []byte
|
baseKey atomic.Value
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func reloadEnvSettings() error {
|
||||||
if strings.ToLower(platform.NewEnvFlag(platform.XUDPLog).GetValue(func() string { return "" })) == "true" {
|
Show.Store(strings.ToLower(platform.NewEnvFlag(platform.XUDPLog).GetValue(func() string { return "" })) == "true")
|
||||||
Show = true
|
raw := platform.NewEnvFlag(platform.XUDPBaseKey).GetValue(func() string { return "" })
|
||||||
|
if raw == "" {
|
||||||
|
ensureBaseKey()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
BaseKey = make([]byte, 32)
|
key, _ := base64.RawURLEncoding.DecodeString(raw)
|
||||||
rand.Read(BaseKey)
|
if len(key) != 32 {
|
||||||
go func() {
|
return errors.New(platform.XUDPBaseKey + ": invalid value (BaseKey must be 32 bytes): " + raw + " len " + strconv.Itoa(len(key)))
|
||||||
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 != "" {
|
baseKey.Store(append([]byte(nil), key...))
|
||||||
if BaseKey, _ = base64.RawURLEncoding.DecodeString(raw); len(BaseKey) == 32 {
|
return nil
|
||||||
return
|
}
|
||||||
}
|
|
||||||
panic(platform.XUDPBaseKey + ": invalid value (BaseKey must be 32 bytes): " + raw + " len " + strconv.Itoa(len(BaseKey)))
|
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetGlobalID(ctx context.Context) (globalID [8]byte) {
|
func GetGlobalID(ctx context.Context) (globalID [8]byte) {
|
||||||
@@ -54,10 +68,10 @@ func GetGlobalID(ctx context.Context) (globalID [8]byte) {
|
|||||||
}
|
}
|
||||||
if inbound := session.InboundFromContext(ctx); inbound != nil && inbound.Source.Network == net.Network_UDP &&
|
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") {
|
(inbound.Name == "dokodemo-door" || inbound.Name == "socks" || inbound.Name == "shadowsocks" || inbound.Name == "tun") {
|
||||||
h := blake3.New(8, BaseKey)
|
h := blake3.New(8, ensureBaseKey())
|
||||||
h.Write([]byte(inbound.Source.String()))
|
h.Write([]byte(inbound.Source.String()))
|
||||||
copy(globalID[:], h.Sum(nil))
|
copy(globalID[:], h.Sum(nil))
|
||||||
if Show {
|
if Show.Load() {
|
||||||
errors.LogInfo(ctx, fmt.Sprintf("XUDP inbound.Source.String(): %v\tglobalID: %v\n", inbound.Source.String(), globalID))
|
errors.LogInfo(ctx, fmt.Sprintf("XUDP inbound.Source.String(): %v\tglobalID: %v\n", inbound.Source.String(), globalID))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -187,6 +187,9 @@ func NewWithContext(ctx context.Context, config *Config) (*Instance, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func initInstanceWithConfig(config *Config, server *Instance) (bool, 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",
|
server.ctx = context.WithValue(server.ctx, "cone",
|
||||||
platform.NewEnvFlag(platform.UseCone).GetValue(func() string { return "" }) != "true")
|
platform.NewEnvFlag(platform.UseCone).GetValue(func() string { return "" }) != "true")
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package policy
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/xtls/xray-core/common/platform"
|
"github.com/xtls/xray-core/common/platform"
|
||||||
@@ -82,32 +83,41 @@ func ManagerType() interface{} {
|
|||||||
return (*Manager)(nil)
|
return (*Manager)(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
var defaultBufferSize int32
|
var defaultBufferSize atomic.Int32
|
||||||
|
|
||||||
func init() {
|
func reloadEnvSettings() error {
|
||||||
|
defaultBufferSize.Store(readDefaultBufferSize())
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func readDefaultBufferSize() int32 {
|
||||||
const defaultValue = -17
|
const defaultValue = -17
|
||||||
size := platform.NewEnvFlag(platform.BufferSize).GetValueAsInt(defaultValue)
|
size := platform.NewEnvFlag(platform.BufferSize).GetValueAsInt(defaultValue)
|
||||||
|
|
||||||
switch size {
|
switch size {
|
||||||
case 0:
|
case 0:
|
||||||
defaultBufferSize = -1 // For pipe to use unlimited size
|
return -1 // For pipe to use unlimited size
|
||||||
case defaultValue: // Env flag not defined. Use default values per CPU-arch.
|
case defaultValue: // Env flag not defined. Use default values per CPU-arch.
|
||||||
switch runtime.GOARCH {
|
switch runtime.GOARCH {
|
||||||
case "arm", "mips", "mipsle":
|
case "arm", "mips", "mipsle":
|
||||||
defaultBufferSize = 0
|
return 0
|
||||||
case "arm64", "mips64", "mips64le":
|
case "arm64", "mips64", "mips64le":
|
||||||
defaultBufferSize = 4 * 1024 // 4k cache for low-end devices
|
return 4 * 1024 // 4k cache for low-end devices
|
||||||
default:
|
default:
|
||||||
defaultBufferSize = 512 * 1024
|
return 512 * 1024
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
defaultBufferSize = int32(size) * 1024 * 1024
|
return int32(size) * 1024 * 1024
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
platform.RegisterEnvReload(reloadEnvSettings)
|
||||||
|
}
|
||||||
|
|
||||||
func defaultBufferPolicy() Buffer {
|
func defaultBufferPolicy() Buffer {
|
||||||
return Buffer{
|
return Buffer{
|
||||||
PerConnection: defaultBufferSize,
|
PerConnection: defaultBufferSize.Load(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@ package conf
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@@ -379,11 +380,20 @@ func (c *StatsConfig) Build() (*stats.Config, error) {
|
|||||||
return &stats.Config{}, nil
|
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 {
|
type Config struct {
|
||||||
// Deprecated: Global transport config is no longer used
|
// Deprecated: Global transport config is no longer used
|
||||||
// left for returning error
|
// left for returning error
|
||||||
Transport map[string]json.RawMessage `json:"transport"`
|
Transport map[string]json.RawMessage `json:"transport"`
|
||||||
|
|
||||||
|
Env EnvConfig `json:"env"`
|
||||||
LogConfig *LogConfig `json:"log"`
|
LogConfig *LogConfig `json:"log"`
|
||||||
RouterConfig *RouterConfig `json:"routing"`
|
RouterConfig *RouterConfig `json:"routing"`
|
||||||
DNSConfig *DNSConfig `json:"dns"`
|
DNSConfig *DNSConfig `json:"dns"`
|
||||||
@@ -439,6 +449,12 @@ func (c *Config) Override(o *Config, fn string) {
|
|||||||
if o.Transport != nil {
|
if o.Transport != nil {
|
||||||
c.Transport = o.Transport
|
c.Transport = o.Transport
|
||||||
}
|
}
|
||||||
|
if o.Env != nil {
|
||||||
|
if c.Env == nil {
|
||||||
|
c.Env = EnvConfig{}
|
||||||
|
}
|
||||||
|
c.Env.Override(o.Env)
|
||||||
|
}
|
||||||
if o.Policy != nil {
|
if o.Policy != nil {
|
||||||
c.Policy = o.Policy
|
c.Policy = o.Policy
|
||||||
}
|
}
|
||||||
@@ -514,6 +530,12 @@ func (c *Config) Override(o *Config, fn string) {
|
|||||||
|
|
||||||
// Build implements Buildable.
|
// Build implements Buildable.
|
||||||
func (c *Config) Build() (*core.Config, error) {
|
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 {
|
if err := PostProcessConfigureFile(c); err != nil {
|
||||||
return nil, errors.New("failed to post-process configuration file").Base(err)
|
return nil, errors.New("failed to post-process configuration file").Base(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,6 +36,10 @@ The -confdir=dir flag sets a dir with multiple json config
|
|||||||
The -format=json flag sets the format of config files.
|
The -format=json flag sets the format of config files.
|
||||||
Default "auto".
|
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,
|
The -test flag tells Xray to test config files only,
|
||||||
without launching the server.
|
without launching the server.
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"io"
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pires/go-proxyproto"
|
"github.com/pires/go-proxyproto"
|
||||||
@@ -31,12 +32,24 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
useSplice bool
|
useSplice atomic.Bool
|
||||||
allNetworks [8]bool
|
allNetworks [8]bool
|
||||||
defaultBlockPrivateRule *FinalRule
|
defaultBlockPrivateRule *FinalRule
|
||||||
defaultBlockAllRule *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() {
|
func init() {
|
||||||
common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
|
common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
|
||||||
h := new(Handler)
|
h := new(Handler)
|
||||||
@@ -48,12 +61,7 @@ func init() {
|
|||||||
return h, nil
|
return h, nil
|
||||||
}))
|
}))
|
||||||
|
|
||||||
const defaultFlagValue = "NOT_DEFINED_AT_ALL"
|
platform.RegisterEnvReload(reloadEnvSettings)
|
||||||
value := platform.NewEnvFlag(platform.UseFreedomSplice).GetValue(func() string { return defaultFlagValue })
|
|
||||||
switch value {
|
|
||||||
case defaultFlagValue, "auto", "enable":
|
|
||||||
useSplice = true
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := range allNetworks {
|
for i := range allNetworks {
|
||||||
allNetworks[i] = true
|
allNetworks[i] = true
|
||||||
@@ -422,7 +430,7 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
|
|||||||
|
|
||||||
responseDone := func() error {
|
responseDone := func() error {
|
||||||
defer timer.SetTimeout(plcy.Timeouts.UplinkOnly)
|
defer timer.SetTimeout(plcy.Timeouts.UplinkOnly)
|
||||||
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
|
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
|
||||||
var writeConn net.Conn
|
var writeConn net.Conn
|
||||||
var inTimer *signal.ActivityTimer
|
var inTimer *signal.ActivityTimer
|
||||||
if inbound := session.InboundFromContext(ctx); inbound != nil && inbound.Conn != nil {
|
if inbound := session.InboundFromContext(ctx); inbound != nil && inbound.Conn != nil {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"crypto/hmac"
|
"crypto/hmac"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"hash/crc64"
|
"hash/crc64"
|
||||||
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/xtls/xray-core/common"
|
"github.com/xtls/xray-core/common"
|
||||||
@@ -218,10 +219,17 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var enablePadding = false
|
var enablePadding atomic.Bool
|
||||||
|
|
||||||
func shouldEnablePadding(s protocol.SecurityType) bool {
|
func shouldEnablePadding(s protocol.SecurityType) bool {
|
||||||
return enablePadding || s == protocol.SecurityType_AES128_GCM || s == protocol.SecurityType_CHACHA20_POLY1305 || s == protocol.SecurityType_AUTO
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@@ -229,10 +237,5 @@ func init() {
|
|||||||
return New(ctx, config.(*Config))
|
return New(ctx, config.(*Config))
|
||||||
}))
|
}))
|
||||||
|
|
||||||
const defaultFlagValue = "NOT_DEFINED_AT_ALL"
|
platform.RegisterEnvReload(reloadEnvSettings)
|
||||||
|
|
||||||
paddingValue := platform.NewEnvFlag(platform.UseVmessPadding).GetValue(func() string { return defaultFlagValue })
|
|
||||||
if paddingValue != defaultFlagValue {
|
|
||||||
enablePadding = true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,9 +27,10 @@ type task struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
conns chan *websocket.Conn
|
conns chan *websocket.Conn
|
||||||
server *http.Server
|
server *http.Server
|
||||||
mu sync.Mutex
|
currentAddr string
|
||||||
|
mu sync.Mutex
|
||||||
)
|
)
|
||||||
|
|
||||||
var upgrader = &websocket.Upgrader{
|
var upgrader = &websocket.Upgrader{
|
||||||
@@ -47,8 +48,13 @@ func Reload() {
|
|||||||
mu.Lock()
|
mu.Lock()
|
||||||
defer mu.Unlock()
|
defer mu.Unlock()
|
||||||
|
|
||||||
|
if addr == currentAddr && (addr == "" || server != nil) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if server != nil {
|
if server != nil {
|
||||||
server.Close()
|
server.Close()
|
||||||
|
server = nil
|
||||||
}
|
}
|
||||||
if HasBrowserDialer() {
|
if HasBrowserDialer() {
|
||||||
for len(conns) > 0 {
|
for len(conns) > 0 {
|
||||||
@@ -60,6 +66,7 @@ func Reload() {
|
|||||||
}
|
}
|
||||||
conns = nil
|
conns = nil
|
||||||
}
|
}
|
||||||
|
currentAddr = addr
|
||||||
if addr != "" {
|
if addr != "" {
|
||||||
token := uuid.New()
|
token := uuid.New()
|
||||||
csrfToken := token.String()
|
csrfToken := token.String()
|
||||||
@@ -220,5 +227,8 @@ func CheckOK(conn *websocket.Conn) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
Reload()
|
platform.RegisterEnvReload(func() error {
|
||||||
|
Reload()
|
||||||
|
return nil
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user