From ee15cc253f5576bc393895a9ddd2e90bf1f4fda0 Mon Sep 17 00:00:00 2001 From: RPRX <63339210+rprx@users.noreply.github.com> Date: Sun, 10 Jan 2021 07:50:21 +0000 Subject: [PATCH] Improve configuration detector (cone or symmetric) --- app/proxyman/inbound/always.go | 1 + app/proxyman/inbound/dynamic.go | 1 + app/proxyman/inbound/worker.go | 7 ++++++- common/buf/buffer.go | 2 -- core/xray.go | 30 ++++++++++++++++++++++++++++++ main/run.go | 24 ------------------------ proxy/shadowsocks/server.go | 4 +++- proxy/socks/server.go | 4 +++- proxy/trojan/server.go | 4 +++- 9 files changed, 47 insertions(+), 30 deletions(-) diff --git a/app/proxyman/inbound/always.go b/app/proxyman/inbound/always.go index 43174a0f..27716971 100644 --- a/app/proxyman/inbound/always.go +++ b/app/proxyman/inbound/always.go @@ -136,6 +136,7 @@ func NewAlwaysOnInboundHandler(ctx context.Context, tag string, receiverConfig * uplinkCounter: uplinkCounter, downlinkCounter: downlinkCounter, stream: mss, + ctx: ctx, } h.workers = append(h.workers, worker) } diff --git a/app/proxyman/inbound/dynamic.go b/app/proxyman/inbound/dynamic.go index f6750976..71e46c46 100644 --- a/app/proxyman/inbound/dynamic.go +++ b/app/proxyman/inbound/dynamic.go @@ -156,6 +156,7 @@ func (h *DynamicInboundHandler) refresh() error { uplinkCounter: uplinkCounter, downlinkCounter: downlinkCounter, stream: h.streamSettings, + ctx: h.ctx, } if err := worker.Start(); err != nil { newError("failed to create UDP worker").Base(err).AtWarning().WriteToLog() diff --git a/app/proxyman/inbound/worker.go b/app/proxyman/inbound/worker.go index 35b4fda0..bfed51d1 100644 --- a/app/proxyman/inbound/worker.go +++ b/app/proxyman/inbound/worker.go @@ -239,6 +239,9 @@ type udpWorker struct { checker *task.Periodic activeConn map[connID]*udpConn + + ctx context.Context + cone bool } func (w *udpWorker) getConnection(id connID) (*udpConn, bool) { @@ -279,7 +282,7 @@ func (w *udpWorker) callback(b *buf.Buffer, source net.Destination, originalDest src: source, } if originalDest.IsValid() { - if !buf.Cone { + if !w.cone { id.dest = originalDest } b.UDP = &originalDest @@ -360,6 +363,8 @@ func (w *udpWorker) Start() error { return err } + w.cone = w.ctx.Value("cone").(bool) + w.checker = &task.Periodic{ Interval: time.Minute, Execute: w.clean, diff --git a/common/buf/buffer.go b/common/buf/buffer.go index 7f636350..a9745b8e 100644 --- a/common/buf/buffer.go +++ b/common/buf/buffer.go @@ -14,8 +14,6 @@ const ( var pool = bytespool.GetPool(Size) -var Cone = true - // Buffer is a recyclable allocation of a byte array. Buffer.Release() recycles // the buffer into an internal buffer pool, in order to recreate a buffer more // quickly. diff --git a/core/xray.go b/core/xray.go index 34454011..3a86d323 100644 --- a/core/xray.go +++ b/core/xray.go @@ -3,8 +3,13 @@ package core import ( "context" "reflect" + "runtime/debug" + "strings" "sync" + "github.com/golang/protobuf/proto" + + "github.com/xtls/xray-core/app/proxyman" "github.com/xtls/xray-core/common" "github.com/xtls/xray-core/common/serial" "github.com/xtls/xray-core/features" @@ -179,6 +184,31 @@ func NewWithContext(ctx context.Context, config *Config) (*Instance, error) { } func initInstanceWithConfig(config *Config, server *Instance) (bool, error) { + cone := true + v, t := false, false + for _, outbound := range config.Outbound { + s := strings.ToLower(outbound.ProxySettings.Type) + l := len(s) + if l >= 16 && s[11:16] == "vless" || l >= 16 && s[11:16] == "vmess" { + v = true + continue + } + if l >= 17 && s[11:17] == "trojan" || l >= 22 && s[11:22] == "shadowsocks" { + t = true + var m proxyman.SenderConfig + proto.Unmarshal(outbound.SenderSettings.Value, &m) + if m.MultiplexSettings != nil && m.MultiplexSettings.Enabled { + cone = false + break + } + } + } + if v && !t { + cone = false + } + server.ctx = context.WithValue(server.ctx, "cone", cone) + defer debug.FreeOSMemory() + if config.Transport != nil { features.PrintDeprecatedFeatureWarning("global transport settings") } diff --git a/main/run.go b/main/run.go index 12243b45..9676952e 100644 --- a/main/run.go +++ b/main/run.go @@ -14,10 +14,6 @@ import ( "strings" "syscall" - "github.com/golang/protobuf/proto" - - "github.com/xtls/xray-core/app/proxyman" - "github.com/xtls/xray-core/common/buf" "github.com/xtls/xray-core/common/cmdarg" "github.com/xtls/xray-core/common/platform" "github.com/xtls/xray-core/core" @@ -185,26 +181,6 @@ func startXray() (core.Server, error) { return nil, newError("failed to load config files: [", configFiles.String(), "]").Base(err) } - v, t := false, false - for _, outbound := range config.Outbound { - s := strings.ToLower(outbound.ProxySettings.Type) - l := len(s) - if l >= 16 && s[11:16] == "vless" || l >= 16 && s[11:16] == "vmess" { - v = true - continue - } - if l >= 17 && s[11:17] == "trojan" || l >= 22 && s[11:22] == "shadowsocks" { - var m proxyman.SenderConfig - proto.Unmarshal(outbound.SenderSettings.Value, &m) - if m.MultiplexSettings == nil || !m.MultiplexSettings.Enabled { - t = true - } - } - } - if v && !t { - buf.Cone = false - } - server, err := core.New(config) if err != nil { return nil, newError("failed to create server").Base(err) diff --git a/proxy/shadowsocks/server.go b/proxy/shadowsocks/server.go index 50e2217e..273f4cc9 100644 --- a/proxy/shadowsocks/server.go +++ b/proxy/shadowsocks/server.go @@ -24,6 +24,7 @@ type Server struct { config *ServerConfig user *protocol.MemoryUser policyManager policy.Manager + cone bool } // NewServer create a new Shadowsocks server. @@ -42,6 +43,7 @@ func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) { config: config, user: mUser, policyManager: v.GetFeature(policy.ManagerType()).(policy.Manager), + cone: ctx.Value("cone").(bool), } return s, nil @@ -144,7 +146,7 @@ func (s *Server) handlerUDPPayload(ctx context.Context, conn internet.Connection data.UDP = &destination - if !buf.Cone || dest == nil { + if !s.cone || dest == nil { dest = &destination } diff --git a/proxy/socks/server.go b/proxy/socks/server.go index 626a9654..8aeb568a 100644 --- a/proxy/socks/server.go +++ b/proxy/socks/server.go @@ -26,6 +26,7 @@ import ( type Server struct { config *ServerConfig policyManager policy.Manager + cone bool } // NewServer creates a new Server object. @@ -34,6 +35,7 @@ func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) { s := &Server{ config: config, policyManager: v.GetFeature(policy.ManagerType()).(policy.Manager), + cone: ctx.Value("cone").(bool), } return s, nil } @@ -261,7 +263,7 @@ func (s *Server) handleUDPPayload(ctx context.Context, conn internet.Connection, payload.UDP = &destination - if !buf.Cone || dest == nil { + if !s.cone || dest == nil { dest = &destination } diff --git a/proxy/trojan/server.go b/proxy/trojan/server.go index da6361ff..c11fa230 100644 --- a/proxy/trojan/server.go +++ b/proxy/trojan/server.go @@ -47,6 +47,7 @@ type Server struct { policyManager policy.Manager validator *Validator fallbacks map[string]map[string]*Fallback // or nil + cone bool } // NewServer creates a new trojan inbound handler. @@ -67,6 +68,7 @@ func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) { server := &Server{ policyManager: v.GetFeature(policy.ManagerType()).(policy.Manager), validator: validator, + cone: ctx.Value("cone").(bool), } if config.Fallbacks != nil { @@ -293,7 +295,7 @@ func (s *Server) handleUDPPayload(ctx context.Context, clientReader *PacketReade } newError("tunnelling request to ", destination).WriteToLog(session.ExportIDToError(ctx)) - if !buf.Cone || dest == nil { + if !s.cone || dest == nil { dest = &destination }