Add runtime warnings

This commit is contained in:
世界 2022-07-24 22:54:16 +08:00
parent 29c329dc52
commit 32e2730ec6
No known key found for this signature in database
GPG key ID: CD109927C34A63C4
29 changed files with 677 additions and 16 deletions

View file

@ -3,10 +3,10 @@ package dialer
import ( import (
"context" "context"
"net" "net"
"runtime"
"time" "time"
"github.com/sagernet/sing-box/adapter" "github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/warning"
C "github.com/sagernet/sing-box/constant" C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/option" "github.com/sagernet/sing-box/option"
"github.com/sagernet/sing/common" "github.com/sagernet/sing/common"
@ -16,6 +16,41 @@ import (
"github.com/database64128/tfo-go" "github.com/database64128/tfo-go"
) )
var warnBindInterfaceOnUnsupportedPlatform = warning.New(
func() bool {
return !(C.IsLinux || C.IsWindows)
},
"outbound option `bind_interface` is only supported on Linux and Windows",
)
var warnRoutingMarkOnUnsupportedPlatform = warning.New(
func() bool {
return !C.IsLinux
},
"outbound option `routing_mark` is only supported on Linux",
)
var warnReuseAdderOnUnsupportedPlatform = warning.New(
func() bool {
return !(C.IsDarwin || C.IsDragonfly || C.IsFreebsd || C.IsLinux || C.IsNetbsd || C.IsOpenbsd || C.IsSolaris || C.IsWindows)
},
"outbound option `reuse_addr` is unsupported on current platform",
)
var warnProtectPathOnNonAndroid = warning.New(
func() bool {
return !C.IsAndroid
},
"outbound option `protect_path` is only supported on Android",
)
var warnTFOOnUnsupportedPlatform = warning.New(
func() bool {
return !(C.IsDarwin || C.IsFreebsd || C.IsLinux || C.IsWindows)
},
"outbound option `tcp_fast_open` is unsupported on current platform",
)
type DefaultDialer struct { type DefaultDialer struct {
tfo.Dialer tfo.Dialer
net.ListenConfig net.ListenConfig
@ -25,10 +60,11 @@ func NewDefault(router adapter.Router, options option.DialerOptions) *DefaultDia
var dialer net.Dialer var dialer net.Dialer
var listener net.ListenConfig var listener net.ListenConfig
if options.BindInterface != "" { if options.BindInterface != "" {
warnBindInterfaceOnUnsupportedPlatform.Check()
dialer.Control = control.Append(dialer.Control, control.BindToInterface(router.InterfaceBindManager(), options.BindInterface)) dialer.Control = control.Append(dialer.Control, control.BindToInterface(router.InterfaceBindManager(), options.BindInterface))
listener.Control = control.Append(listener.Control, control.BindToInterface(router.InterfaceBindManager(), options.BindInterface)) listener.Control = control.Append(listener.Control, control.BindToInterface(router.InterfaceBindManager(), options.BindInterface))
} else if router.AutoDetectInterface() { } else if router.AutoDetectInterface() {
if runtime.GOOS == "windows" { if C.IsWindows {
dialer.Control = control.Append(dialer.Control, control.BindToInterfaceIndexFunc(func() int { dialer.Control = control.Append(dialer.Control, control.BindToInterfaceIndexFunc(func() int {
return router.AutoDetectInterfaceIndex() return router.AutoDetectInterfaceIndex()
})) }))
@ -48,6 +84,7 @@ func NewDefault(router adapter.Router, options option.DialerOptions) *DefaultDia
listener.Control = control.Append(listener.Control, control.BindToInterface(router.InterfaceBindManager(), router.DefaultInterface())) listener.Control = control.Append(listener.Control, control.BindToInterface(router.InterfaceBindManager(), router.DefaultInterface()))
} }
if options.RoutingMark != 0 { if options.RoutingMark != 0 {
warnRoutingMarkOnUnsupportedPlatform.Check()
dialer.Control = control.Append(dialer.Control, control.RoutingMark(options.RoutingMark)) dialer.Control = control.Append(dialer.Control, control.RoutingMark(options.RoutingMark))
listener.Control = control.Append(listener.Control, control.RoutingMark(options.RoutingMark)) listener.Control = control.Append(listener.Control, control.RoutingMark(options.RoutingMark))
} else if router.DefaultMark() != 0 { } else if router.DefaultMark() != 0 {
@ -55,9 +92,11 @@ func NewDefault(router adapter.Router, options option.DialerOptions) *DefaultDia
listener.Control = control.Append(listener.Control, control.RoutingMark(router.DefaultMark())) listener.Control = control.Append(listener.Control, control.RoutingMark(router.DefaultMark()))
} }
if options.ReuseAddr { if options.ReuseAddr {
warnReuseAdderOnUnsupportedPlatform.Check()
listener.Control = control.Append(listener.Control, control.ReuseAddr()) listener.Control = control.Append(listener.Control, control.ReuseAddr())
} }
if options.ProtectPath != "" { if options.ProtectPath != "" {
warnProtectPathOnNonAndroid.Check()
dialer.Control = control.Append(dialer.Control, control.ProtectPath(options.ProtectPath)) dialer.Control = control.Append(dialer.Control, control.ProtectPath(options.ProtectPath))
listener.Control = control.Append(listener.Control, control.ProtectPath(options.ProtectPath)) listener.Control = control.Append(listener.Control, control.ProtectPath(options.ProtectPath))
} }
@ -66,6 +105,9 @@ func NewDefault(router adapter.Router, options option.DialerOptions) *DefaultDia
} else { } else {
dialer.Timeout = C.DefaultTCPTimeout dialer.Timeout = C.DefaultTCPTimeout
} }
if options.TCPFastOpen {
warnTFOOnUnsupportedPlatform.Check()
}
return &DefaultDialer{tfo.Dialer{Dialer: dialer, DisableTFO: !options.TCPFastOpen}, listener} return &DefaultDialer{tfo.Dialer{Dialer: dialer, DisableTFO: !options.TCPFastOpen}, listener}
} }

31
common/warning/warning.go Normal file
View file

@ -0,0 +1,31 @@
package warning
import (
"sync"
"github.com/sagernet/sing-box/log"
)
type Warning struct {
logger log.Logger
check CheckFunc
message string
checkOnce sync.Once
}
type CheckFunc = func() bool
func New(checkFunc CheckFunc, message string) Warning {
return Warning{
check: checkFunc,
message: message,
}
}
func (w *Warning) Check() {
w.checkOnce.Do(func() {
if w.check() {
log.Warn(w.message)
}
})
}

68
constant/goos/gengoos.go Normal file
View file

@ -0,0 +1,68 @@
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build ignore
package main
import (
"bytes"
"fmt"
"log"
"os"
"strconv"
"strings"
)
var gooses []string
func main() {
data, err := os.ReadFile("../../go/build/syslist.go")
if err != nil {
log.Fatal(err)
}
const goosPrefix = `const goosList = `
for _, line := range strings.Split(string(data), "\n") {
if strings.HasPrefix(line, goosPrefix) {
text, err := strconv.Unquote(strings.TrimPrefix(line, goosPrefix))
if err != nil {
log.Fatalf("parsing goosList: %v", err)
}
gooses = strings.Fields(text)
}
}
for _, target := range gooses {
if target == "nacl" {
continue
}
var tags []string
if target == "linux" {
tags = append(tags, "!android") // must explicitly exclude android for linux
}
if target == "solaris" {
tags = append(tags, "!illumos") // must explicitly exclude illumos for solaris
}
if target == "darwin" {
tags = append(tags, "!ios") // must explicitly exclude ios for darwin
}
tags = append(tags, target) // must explicitly include target for bootstrapping purposes
var buf bytes.Buffer
fmt.Fprintf(&buf, "// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.\n\n")
fmt.Fprintf(&buf, "//go:build %s\n", strings.Join(tags, " && "))
fmt.Fprintf(&buf, "package goos\n\n")
fmt.Fprintf(&buf, "const GOOS = `%s`\n\n", target)
for _, goos := range gooses {
value := 0
if goos == target {
value = 1
}
fmt.Fprintf(&buf, "const Is%s = %d\n", strings.Title(goos), value)
}
err := os.WriteFile("zgoos_"+target+".go", buf.Bytes(), 0o666)
if err != nil {
log.Fatal(err)
}
}
}

12
constant/goos/goos.go Normal file
View file

@ -0,0 +1,12 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// package goos contains GOOS-specific constants.
package goos
// The next line makes 'go generate' write the zgoos*.go files with
// per-OS information, including constants named Is$GOOS for every
// known GOOS. The constant is 1 on the current system, 0 otherwise;
// multiplying by them is useful for defining GOOS-specific constants.
//go:generate go run gengoos.go

View file

@ -0,0 +1,25 @@
// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
//go:build aix
package goos
const GOOS = `aix`
const IsAix = 1
const IsAndroid = 0
const IsDarwin = 0
const IsDragonfly = 0
const IsFreebsd = 0
const IsHurd = 0
const IsIllumos = 0
const IsIos = 0
const IsJs = 0
const IsLinux = 0
const IsNacl = 0
const IsNetbsd = 0
const IsOpenbsd = 0
const IsPlan9 = 0
const IsSolaris = 0
const IsWindows = 0
const IsZos = 0

View file

@ -0,0 +1,25 @@
// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
//go:build android
package goos
const GOOS = `android`
const IsAix = 0
const IsAndroid = 1
const IsDarwin = 0
const IsDragonfly = 0
const IsFreebsd = 0
const IsHurd = 0
const IsIllumos = 0
const IsIos = 0
const IsJs = 0
const IsLinux = 0
const IsNacl = 0
const IsNetbsd = 0
const IsOpenbsd = 0
const IsPlan9 = 0
const IsSolaris = 0
const IsWindows = 0
const IsZos = 0

View file

@ -0,0 +1,25 @@
// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
//go:build !ios && darwin
package goos
const GOOS = `darwin`
const IsAix = 0
const IsAndroid = 0
const IsDarwin = 1
const IsDragonfly = 0
const IsFreebsd = 0
const IsHurd = 0
const IsIllumos = 0
const IsIos = 0
const IsJs = 0
const IsLinux = 0
const IsNacl = 0
const IsNetbsd = 0
const IsOpenbsd = 0
const IsPlan9 = 0
const IsSolaris = 0
const IsWindows = 0
const IsZos = 0

View file

@ -0,0 +1,25 @@
// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
//go:build dragonfly
package goos
const GOOS = `dragonfly`
const IsAix = 0
const IsAndroid = 0
const IsDarwin = 0
const IsDragonfly = 1
const IsFreebsd = 0
const IsHurd = 0
const IsIllumos = 0
const IsIos = 0
const IsJs = 0
const IsLinux = 0
const IsNacl = 0
const IsNetbsd = 0
const IsOpenbsd = 0
const IsPlan9 = 0
const IsSolaris = 0
const IsWindows = 0
const IsZos = 0

View file

@ -0,0 +1,25 @@
// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
//go:build freebsd
package goos
const GOOS = `freebsd`
const IsAix = 0
const IsAndroid = 0
const IsDarwin = 0
const IsDragonfly = 0
const IsFreebsd = 1
const IsHurd = 0
const IsIllumos = 0
const IsIos = 0
const IsJs = 0
const IsLinux = 0
const IsNacl = 0
const IsNetbsd = 0
const IsOpenbsd = 0
const IsPlan9 = 0
const IsSolaris = 0
const IsWindows = 0
const IsZos = 0

View file

@ -0,0 +1,25 @@
// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
//go:build hurd
package goos
const GOOS = `hurd`
const IsAix = 0
const IsAndroid = 0
const IsDarwin = 0
const IsDragonfly = 0
const IsFreebsd = 0
const IsHurd = 1
const IsIllumos = 0
const IsIos = 0
const IsJs = 0
const IsLinux = 0
const IsNacl = 0
const IsNetbsd = 0
const IsOpenbsd = 0
const IsPlan9 = 0
const IsSolaris = 0
const IsWindows = 0
const IsZos = 0

View file

@ -0,0 +1,25 @@
// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
//go:build illumos
package goos
const GOOS = `illumos`
const IsAix = 0
const IsAndroid = 0
const IsDarwin = 0
const IsDragonfly = 0
const IsFreebsd = 0
const IsHurd = 0
const IsIllumos = 1
const IsIos = 0
const IsJs = 0
const IsLinux = 0
const IsNacl = 0
const IsNetbsd = 0
const IsOpenbsd = 0
const IsPlan9 = 0
const IsSolaris = 0
const IsWindows = 0
const IsZos = 0

View file

@ -0,0 +1,25 @@
// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
//go:build ios
package goos
const GOOS = `ios`
const IsAix = 0
const IsAndroid = 0
const IsDarwin = 0
const IsDragonfly = 0
const IsFreebsd = 0
const IsHurd = 0
const IsIllumos = 0
const IsIos = 1
const IsJs = 0
const IsLinux = 0
const IsNacl = 0
const IsNetbsd = 0
const IsOpenbsd = 0
const IsPlan9 = 0
const IsSolaris = 0
const IsWindows = 0
const IsZos = 0

25
constant/goos/zgoos_js.go Normal file
View file

@ -0,0 +1,25 @@
// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
//go:build js
package goos
const GOOS = `js`
const IsAix = 0
const IsAndroid = 0
const IsDarwin = 0
const IsDragonfly = 0
const IsFreebsd = 0
const IsHurd = 0
const IsIllumos = 0
const IsIos = 0
const IsJs = 1
const IsLinux = 0
const IsNacl = 0
const IsNetbsd = 0
const IsOpenbsd = 0
const IsPlan9 = 0
const IsSolaris = 0
const IsWindows = 0
const IsZos = 0

View file

@ -0,0 +1,25 @@
// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
//go:build !android && linux
package goos
const GOOS = `linux`
const IsAix = 0
const IsAndroid = 0
const IsDarwin = 0
const IsDragonfly = 0
const IsFreebsd = 0
const IsHurd = 0
const IsIllumos = 0
const IsIos = 0
const IsJs = 0
const IsLinux = 1
const IsNacl = 0
const IsNetbsd = 0
const IsOpenbsd = 0
const IsPlan9 = 0
const IsSolaris = 0
const IsWindows = 0
const IsZos = 0

View file

@ -0,0 +1,25 @@
// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
//go:build netbsd
package goos
const GOOS = `netbsd`
const IsAix = 0
const IsAndroid = 0
const IsDarwin = 0
const IsDragonfly = 0
const IsFreebsd = 0
const IsHurd = 0
const IsIllumos = 0
const IsIos = 0
const IsJs = 0
const IsLinux = 0
const IsNacl = 0
const IsNetbsd = 1
const IsOpenbsd = 0
const IsPlan9 = 0
const IsSolaris = 0
const IsWindows = 0
const IsZos = 0

View file

@ -0,0 +1,25 @@
// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
//go:build openbsd
package goos
const GOOS = `openbsd`
const IsAix = 0
const IsAndroid = 0
const IsDarwin = 0
const IsDragonfly = 0
const IsFreebsd = 0
const IsHurd = 0
const IsIllumos = 0
const IsIos = 0
const IsJs = 0
const IsLinux = 0
const IsNacl = 0
const IsNetbsd = 0
const IsOpenbsd = 1
const IsPlan9 = 0
const IsSolaris = 0
const IsWindows = 0
const IsZos = 0

View file

@ -0,0 +1,25 @@
// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
//go:build plan9
package goos
const GOOS = `plan9`
const IsAix = 0
const IsAndroid = 0
const IsDarwin = 0
const IsDragonfly = 0
const IsFreebsd = 0
const IsHurd = 0
const IsIllumos = 0
const IsIos = 0
const IsJs = 0
const IsLinux = 0
const IsNacl = 0
const IsNetbsd = 0
const IsOpenbsd = 0
const IsPlan9 = 1
const IsSolaris = 0
const IsWindows = 0
const IsZos = 0

View file

@ -0,0 +1,25 @@
// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
//go:build !illumos && solaris
package goos
const GOOS = `solaris`
const IsAix = 0
const IsAndroid = 0
const IsDarwin = 0
const IsDragonfly = 0
const IsFreebsd = 0
const IsHurd = 0
const IsIllumos = 0
const IsIos = 0
const IsJs = 0
const IsLinux = 0
const IsNacl = 0
const IsNetbsd = 0
const IsOpenbsd = 0
const IsPlan9 = 0
const IsSolaris = 1
const IsWindows = 0
const IsZos = 0

View file

@ -0,0 +1,25 @@
// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
//go:build windows
package goos
const GOOS = `windows`
const IsAix = 0
const IsAndroid = 0
const IsDarwin = 0
const IsDragonfly = 0
const IsFreebsd = 0
const IsHurd = 0
const IsIllumos = 0
const IsIos = 0
const IsJs = 0
const IsLinux = 0
const IsNacl = 0
const IsNetbsd = 0
const IsOpenbsd = 0
const IsPlan9 = 0
const IsSolaris = 0
const IsWindows = 1
const IsZos = 0

View file

@ -0,0 +1,25 @@
// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
//go:build zos
package goos
const GOOS = `zos`
const IsAix = 0
const IsAndroid = 0
const IsDarwin = 0
const IsDragonfly = 0
const IsFreebsd = 0
const IsHurd = 0
const IsIllumos = 0
const IsIos = 0
const IsJs = 0
const IsLinux = 0
const IsNacl = 0
const IsNetbsd = 0
const IsOpenbsd = 0
const IsPlan9 = 0
const IsSolaris = 0
const IsWindows = 0
const IsZos = 1

37
constant/os.go Normal file
View file

@ -0,0 +1,37 @@
package constant
import (
"github.com/sagernet/sing-box/constant/goos"
)
const IsAndroid = goos.IsAndroid == 1
const IsDarwin = goos.IsDarwin == 1
const IsDragonfly = goos.IsDragonfly == 1
const IsFreebsd = goos.IsFreebsd == 1
const IsHurd = goos.IsHurd == 1
const IsIllumos = goos.IsIllumos == 1
const IsIos = goos.IsIos == 1
const IsJs = goos.IsJs == 1
const IsLinux = goos.IsLinux == 1
const IsNacl = goos.IsNacl == 1
const IsNetbsd = goos.IsNetbsd == 1
const IsOpenbsd = goos.IsOpenbsd == 1
const IsPlan9 = goos.IsPlan9 == 1
const IsSolaris = goos.IsSolaris == 1
const IsWindows = goos.IsWindows == 1
const IsZos = goos.IsZos == 1

View file

@ -6,7 +6,6 @@ import (
"context" "context"
"net" "net"
"net/netip" "net/netip"
"runtime"
"strconv" "strconv"
"strings" "strings"
@ -140,10 +139,9 @@ func (t *Tun) NewError(ctx context.Context, err error) {
} }
func mkInterfaceName() (tunName string) { func mkInterfaceName() (tunName string) {
switch runtime.GOOS { if C.IsDarwin {
case "darwin":
tunName = "utun" tunName = "utun"
default: } else {
tunName = "tun" tunName = "tun"
} }
interfaces, err := net.Interfaces() interfaces, err := net.Interfaces()

View file

@ -21,6 +21,7 @@ import (
"github.com/sagernet/sing-box/common/process" "github.com/sagernet/sing-box/common/process"
"github.com/sagernet/sing-box/common/sniff" "github.com/sagernet/sing-box/common/sniff"
"github.com/sagernet/sing-box/common/urltest" "github.com/sagernet/sing-box/common/urltest"
"github.com/sagernet/sing-box/common/warning"
C "github.com/sagernet/sing-box/constant" C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log" "github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option" "github.com/sagernet/sing-box/option"
@ -38,6 +39,27 @@ import (
"golang.org/x/net/dns/dnsmessage" "golang.org/x/net/dns/dnsmessage"
) )
var warnDefaultInterfaceOnUnsupportedPlatform = warning.New(
func() bool {
return !(C.IsLinux || C.IsWindows)
},
"route option `default_mark` is only supported on Linux and Windows",
)
var warnDefaultMarkOnNonLinux = warning.New(
func() bool {
return !C.IsLinux
},
"route option `default_mark` is only supported on Linux",
)
var warnFindProcessOnUnsupportedPlatform = warning.New(
func() bool {
return !(C.IsLinux || C.IsWindows || C.IsDarwin)
},
"route option `find_process` is only supported on Linux, Windows, and Mac OS X",
)
var _ adapter.Router = (*Router)(nil) var _ adapter.Router = (*Router)(nil)
type Router struct { type Router struct {
@ -75,6 +97,16 @@ type Router struct {
} }
func NewRouter(ctx context.Context, logger log.ContextLogger, dnsLogger log.ContextLogger, options option.RouteOptions, dnsOptions option.DNSOptions) (*Router, error) { func NewRouter(ctx context.Context, logger log.ContextLogger, dnsLogger log.ContextLogger, options option.RouteOptions, dnsOptions option.DNSOptions) (*Router, error) {
if options.DefaultInterface != "" {
warnDefaultInterfaceOnUnsupportedPlatform.Check()
}
if options.DefaultMark != 0 {
warnDefaultMarkOnNonLinux.Check()
}
if options.FindProcess {
warnFindProcessOnUnsupportedPlatform.Check()
}
router := &Router{ router := &Router{
ctx: ctx, ctx: ctx,
logger: logger, logger: logger,
@ -225,9 +257,12 @@ func NewRouter(ctx context.Context, logger log.ContextLogger, dnsLogger log.Cont
if hasRule(options.Rules, isProcessRule) || hasDNSRule(dnsOptions.Rules, isProcessDNSRule) || options.FindProcess { if hasRule(options.Rules, isProcessRule) || hasDNSRule(dnsOptions.Rules, isProcessDNSRule) || options.FindProcess {
searcher, err := process.NewSearcher(logger) searcher, err := process.NewSearcher(logger)
if err != nil { if err != nil {
return nil, E.Cause(err, "create process searcher") if err != os.ErrInvalid {
logger.Warn(E.Cause(err, "create process searcher"))
}
} else {
router.processSearcher = searcher
} }
router.processSearcher = searcher
} }
return router, nil return router, nil
} }
@ -388,7 +423,8 @@ func (r *Router) Start() error {
if starter, isStarter := r.processSearcher.(common.Starter); isStarter { if starter, isStarter := r.processSearcher.(common.Starter); isStarter {
err := starter.Start() err := starter.Start()
if err != nil { if err != nil {
return E.Cause(err, "initialize process searcher") r.logger.Error(E.Cause(err, "initialize process searcher"))
r.processSearcher = nil
} }
} }
} }

View file

@ -4,6 +4,13 @@ import (
"strings" "strings"
"github.com/sagernet/sing-box/adapter" "github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/warning"
C "github.com/sagernet/sing-box/constant"
)
var warnPackageNameOnNonAndroid = warning.New(
func() bool { return !C.IsAndroid },
"rule item `package_name` is only supported on Android",
) )
var _ RuleItem = (*PackageNameItem)(nil) var _ RuleItem = (*PackageNameItem)(nil)
@ -14,6 +21,7 @@ type PackageNameItem struct {
} }
func NewPackageNameItem(packageNameList []string) *PackageNameItem { func NewPackageNameItem(packageNameList []string) *PackageNameItem {
warnPackageNameOnNonAndroid.Check()
rule := &PackageNameItem{ rule := &PackageNameItem{
packageNames: packageNameList, packageNames: packageNameList,
packageMap: make(map[string]bool), packageMap: make(map[string]bool),

View file

@ -5,6 +5,13 @@ import (
"strings" "strings"
"github.com/sagernet/sing-box/adapter" "github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/warning"
C "github.com/sagernet/sing-box/constant"
)
var warnProcessNameOnNonSupportedPlatform = warning.New(
func() bool { return !(C.IsLinux || C.IsWindows || C.IsDarwin) },
"rule item `process_item` is only supported on Linux, Windows, and Mac OS X",
) )
var _ RuleItem = (*ProcessItem)(nil) var _ RuleItem = (*ProcessItem)(nil)
@ -15,6 +22,7 @@ type ProcessItem struct {
} }
func NewProcessItem(processNameList []string) *ProcessItem { func NewProcessItem(processNameList []string) *ProcessItem {
warnProcessNameOnNonSupportedPlatform.Check()
rule := &ProcessItem{ rule := &ProcessItem{
processes: processNameList, processes: processNameList,
processMap: make(map[string]bool), processMap: make(map[string]bool),

View file

@ -4,9 +4,22 @@ import (
"strings" "strings"
"github.com/sagernet/sing-box/adapter" "github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/warning"
C "github.com/sagernet/sing-box/constant"
F "github.com/sagernet/sing/common/format" F "github.com/sagernet/sing/common/format"
) )
var (
warnUserOnNonLinux = warning.New(
func() bool { return !C.IsLinux },
"rule item `user` is only supported on Linux",
)
warnUserOnCGODisabled = warning.New(
func() bool { return !C.CGO_ENABLED },
"rule item `user` is only supported with CGO enabled, rebuild with CGO_ENABLED=1",
)
)
var _ RuleItem = (*UserItem)(nil) var _ RuleItem = (*UserItem)(nil)
type UserItem struct { type UserItem struct {
@ -15,6 +28,8 @@ type UserItem struct {
} }
func NewUserItem(users []string) *UserItem { func NewUserItem(users []string) *UserItem {
warnUserOnNonLinux.Check()
warnUserOnCGODisabled.Check()
userMap := make(map[string]bool) userMap := make(map[string]bool)
for _, protocol := range users { for _, protocol := range users {
userMap[protocol] = true userMap[protocol] = true

View file

@ -4,9 +4,16 @@ import (
"strings" "strings"
"github.com/sagernet/sing-box/adapter" "github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/warning"
C "github.com/sagernet/sing-box/constant"
F "github.com/sagernet/sing/common/format" F "github.com/sagernet/sing/common/format"
) )
var warnUserIDOnNonLinux = warning.New(
func() bool { return !C.IsLinux },
"rule item `user_id` is only supported on Linux",
)
var _ RuleItem = (*UserIdItem)(nil) var _ RuleItem = (*UserIdItem)(nil)
type UserIdItem struct { type UserIdItem struct {
@ -15,6 +22,7 @@ type UserIdItem struct {
} }
func NewUserIDItem(userIdList []int32) *UserIdItem { func NewUserIDItem(userIdList []int32) *UserIdItem {
warnUserIDOnNonLinux.Check()
rule := &UserIdItem{ rule := &UserIdItem{
userIds: userIdList, userIds: userIdList,
userIdMap: make(map[int32]bool), userIdMap: make(map[int32]bool),

View file

@ -8,11 +8,11 @@ import (
"io" "io"
"net" "net"
"net/netip" "net/netip"
"runtime"
"sync" "sync"
"testing" "testing"
"time" "time"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log" "github.com/sagernet/sing-box/log"
"github.com/sagernet/sing/common/control" "github.com/sagernet/sing/common/control"
F "github.com/sagernet/sing/common/format" F "github.com/sagernet/sing/common/format"
@ -37,13 +37,10 @@ var allImages = []string{
ImageV2RayCore, ImageV2RayCore,
} }
var ( var localIP = netip.MustParseAddr("127.0.0.1")
localIP = netip.MustParseAddr("127.0.0.1")
isDarwin = runtime.GOOS == "darwin"
)
func init() { func init() {
if isDarwin { if C.IsDarwin {
var err error var err error
localIP, err = defaultRouteIP() localIP, err = defaultRouteIP()
if err != nil { if err != nil {

View file

@ -5,6 +5,7 @@ import (
"testing" "testing"
"time" "time"
C "github.com/sagernet/sing-box/constant"
F "github.com/sagernet/sing/common/format" F "github.com/sagernet/sing/common/format"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
@ -47,7 +48,7 @@ func startDockerContainer(t *testing.T, options DockerOptions) {
containerOptions.ExposedPorts = make(nat.PortSet) containerOptions.ExposedPorts = make(nat.PortSet)
var hostOptions container.HostConfig var hostOptions container.HostConfig
if !isDarwin { if !C.IsDarwin {
hostOptions.NetworkMode = "host" hostOptions.NetworkMode = "host"
} }
hostOptions.PortBindings = make(nat.PortMap) hostOptions.PortBindings = make(nat.PortMap)