Improve configuration detector (cone or symmetric)

This commit is contained in:
RPRX 2021-01-10 07:50:21 +00:00 committed by GitHub
parent 43eb5d1b25
commit ee15cc253f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 47 additions and 30 deletions

View file

@ -136,6 +136,7 @@ func NewAlwaysOnInboundHandler(ctx context.Context, tag string, receiverConfig *
uplinkCounter: uplinkCounter, uplinkCounter: uplinkCounter,
downlinkCounter: downlinkCounter, downlinkCounter: downlinkCounter,
stream: mss, stream: mss,
ctx: ctx,
} }
h.workers = append(h.workers, worker) h.workers = append(h.workers, worker)
} }

View file

@ -156,6 +156,7 @@ func (h *DynamicInboundHandler) refresh() error {
uplinkCounter: uplinkCounter, uplinkCounter: uplinkCounter,
downlinkCounter: downlinkCounter, downlinkCounter: downlinkCounter,
stream: h.streamSettings, stream: h.streamSettings,
ctx: h.ctx,
} }
if err := worker.Start(); err != nil { if err := worker.Start(); err != nil {
newError("failed to create UDP worker").Base(err).AtWarning().WriteToLog() newError("failed to create UDP worker").Base(err).AtWarning().WriteToLog()

View file

@ -239,6 +239,9 @@ type udpWorker struct {
checker *task.Periodic checker *task.Periodic
activeConn map[connID]*udpConn activeConn map[connID]*udpConn
ctx context.Context
cone bool
} }
func (w *udpWorker) getConnection(id connID) (*udpConn, 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, src: source,
} }
if originalDest.IsValid() { if originalDest.IsValid() {
if !buf.Cone { if !w.cone {
id.dest = originalDest id.dest = originalDest
} }
b.UDP = &originalDest b.UDP = &originalDest
@ -360,6 +363,8 @@ func (w *udpWorker) Start() error {
return err return err
} }
w.cone = w.ctx.Value("cone").(bool)
w.checker = &task.Periodic{ w.checker = &task.Periodic{
Interval: time.Minute, Interval: time.Minute,
Execute: w.clean, Execute: w.clean,

View file

@ -14,8 +14,6 @@ const (
var pool = bytespool.GetPool(Size) var pool = bytespool.GetPool(Size)
var Cone = true
// Buffer is a recyclable allocation of a byte array. Buffer.Release() recycles // 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 // the buffer into an internal buffer pool, in order to recreate a buffer more
// quickly. // quickly.

View file

@ -3,8 +3,13 @@ package core
import ( import (
"context" "context"
"reflect" "reflect"
"runtime/debug"
"strings"
"sync" "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"
"github.com/xtls/xray-core/common/serial" "github.com/xtls/xray-core/common/serial"
"github.com/xtls/xray-core/features" "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) { 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 { if config.Transport != nil {
features.PrintDeprecatedFeatureWarning("global transport settings") features.PrintDeprecatedFeatureWarning("global transport settings")
} }

View file

@ -14,10 +14,6 @@ import (
"strings" "strings"
"syscall" "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/cmdarg"
"github.com/xtls/xray-core/common/platform" "github.com/xtls/xray-core/common/platform"
"github.com/xtls/xray-core/core" "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) 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) server, err := core.New(config)
if err != nil { if err != nil {
return nil, newError("failed to create server").Base(err) return nil, newError("failed to create server").Base(err)

View file

@ -24,6 +24,7 @@ type Server struct {
config *ServerConfig config *ServerConfig
user *protocol.MemoryUser user *protocol.MemoryUser
policyManager policy.Manager policyManager policy.Manager
cone bool
} }
// NewServer create a new Shadowsocks server. // NewServer create a new Shadowsocks server.
@ -42,6 +43,7 @@ func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) {
config: config, config: config,
user: mUser, user: mUser,
policyManager: v.GetFeature(policy.ManagerType()).(policy.Manager), policyManager: v.GetFeature(policy.ManagerType()).(policy.Manager),
cone: ctx.Value("cone").(bool),
} }
return s, nil return s, nil
@ -144,7 +146,7 @@ func (s *Server) handlerUDPPayload(ctx context.Context, conn internet.Connection
data.UDP = &destination data.UDP = &destination
if !buf.Cone || dest == nil { if !s.cone || dest == nil {
dest = &destination dest = &destination
} }

View file

@ -26,6 +26,7 @@ import (
type Server struct { type Server struct {
config *ServerConfig config *ServerConfig
policyManager policy.Manager policyManager policy.Manager
cone bool
} }
// NewServer creates a new Server object. // NewServer creates a new Server object.
@ -34,6 +35,7 @@ func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) {
s := &Server{ s := &Server{
config: config, config: config,
policyManager: v.GetFeature(policy.ManagerType()).(policy.Manager), policyManager: v.GetFeature(policy.ManagerType()).(policy.Manager),
cone: ctx.Value("cone").(bool),
} }
return s, nil return s, nil
} }
@ -261,7 +263,7 @@ func (s *Server) handleUDPPayload(ctx context.Context, conn internet.Connection,
payload.UDP = &destination payload.UDP = &destination
if !buf.Cone || dest == nil { if !s.cone || dest == nil {
dest = &destination dest = &destination
} }

View file

@ -47,6 +47,7 @@ type Server struct {
policyManager policy.Manager policyManager policy.Manager
validator *Validator validator *Validator
fallbacks map[string]map[string]*Fallback // or nil fallbacks map[string]map[string]*Fallback // or nil
cone bool
} }
// NewServer creates a new trojan inbound handler. // NewServer creates a new trojan inbound handler.
@ -67,6 +68,7 @@ func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) {
server := &Server{ server := &Server{
policyManager: v.GetFeature(policy.ManagerType()).(policy.Manager), policyManager: v.GetFeature(policy.ManagerType()).(policy.Manager),
validator: validator, validator: validator,
cone: ctx.Value("cone").(bool),
} }
if config.Fallbacks != nil { 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)) newError("tunnelling request to ", destination).WriteToLog(session.ExportIDToError(ctx))
if !buf.Cone || dest == nil { if !s.cone || dest == nil {
dest = &destination dest = &destination
} }