mirror of
https://github.com/SagerNet/sing-box.git
synced 2024-11-22 08:31:30 +00:00
Add deprecated warnings
This commit is contained in:
parent
8c143feec8
commit
d66d5cd457
|
@ -7,8 +7,10 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/sagernet/sing-box/experimental/deprecated"
|
||||||
_ "github.com/sagernet/sing-box/include"
|
_ "github.com/sagernet/sing-box/include"
|
||||||
"github.com/sagernet/sing-box/log"
|
"github.com/sagernet/sing-box/log"
|
||||||
|
"github.com/sagernet/sing/service"
|
||||||
"github.com/sagernet/sing/service/filemanager"
|
"github.com/sagernet/sing/service/filemanager"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
@ -65,4 +67,5 @@ func preRun(cmd *cobra.Command, args []string) {
|
||||||
if len(configPaths) == 0 && len(configDirectories) == 0 {
|
if len(configPaths) == 0 && len(configDirectories) == 0 {
|
||||||
configPaths = append(configPaths, "config.json")
|
configPaths = append(configPaths, "config.json")
|
||||||
}
|
}
|
||||||
|
globalCtx = service.ContextWith(globalCtx, deprecated.NewEnvManager(log.StdLogger()))
|
||||||
}
|
}
|
||||||
|
|
86
experimental/deprecated/constants.go
Normal file
86
experimental/deprecated/constants.go
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
package deprecated
|
||||||
|
|
||||||
|
import (
|
||||||
|
C "github.com/sagernet/sing-box/constant"
|
||||||
|
F "github.com/sagernet/sing/common/format"
|
||||||
|
|
||||||
|
"golang.org/x/mod/semver"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Note struct {
|
||||||
|
Name string
|
||||||
|
Description string
|
||||||
|
DeprecatedVersion string
|
||||||
|
ScheduledVersion string
|
||||||
|
EnvName string
|
||||||
|
MigrationLink string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n Note) Impending() bool {
|
||||||
|
if n.ScheduledVersion == "" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if !semver.IsValid("v" + C.Version) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
versionMinor := semver.Compare(semver.MajorMinor("v"+C.Version), "v"+n.ScheduledVersion)
|
||||||
|
if versionMinor < 0 {
|
||||||
|
panic("invalid deprecated note: " + n.Name)
|
||||||
|
}
|
||||||
|
return versionMinor <= 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n Note) Message() string {
|
||||||
|
return F.ToString(
|
||||||
|
n.Description, " is deprecated in sing-box ", n.DeprecatedVersion,
|
||||||
|
" and will be removed in sing-box ", n.ScheduledVersion, ", please checkout documentation for migration.",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n Note) MessageWithLink() string {
|
||||||
|
return F.ToString(
|
||||||
|
n.Description, " is deprecated in sing-box ", n.DeprecatedVersion,
|
||||||
|
" and will be removed in sing-box ", n.ScheduledVersion, ", checkout documentation for migration: ", n.MigrationLink,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
var OptionBadMatchSource = Note{
|
||||||
|
Name: "bad-match-source",
|
||||||
|
Description: "legacy match source rule item",
|
||||||
|
DeprecatedVersion: "1.10.0",
|
||||||
|
ScheduledVersion: "1.11.0",
|
||||||
|
MigrationLink: "https://sing-box.sagernet.org/deprecated/#match-source-rule-items-are-renamed",
|
||||||
|
}
|
||||||
|
|
||||||
|
var OptionGEOIP = Note{
|
||||||
|
Name: "geoip",
|
||||||
|
Description: "geoip database",
|
||||||
|
DeprecatedVersion: "1.8.0",
|
||||||
|
ScheduledVersion: "1.12.0",
|
||||||
|
EnvName: "GEOIP",
|
||||||
|
MigrationLink: "https://sing-box.sagernet.org/migration/#migrate-geoip-to-rule-sets",
|
||||||
|
}
|
||||||
|
|
||||||
|
var OptionGEOSITE = Note{
|
||||||
|
Name: "geosite",
|
||||||
|
Description: "geosite database",
|
||||||
|
DeprecatedVersion: "1.8.0",
|
||||||
|
ScheduledVersion: "1.12.0",
|
||||||
|
EnvName: "GEOSITE",
|
||||||
|
MigrationLink: "https://sing-box.sagernet.org/migration/#migrate-geosite-to-rule-sets",
|
||||||
|
}
|
||||||
|
|
||||||
|
var OptionTUNAddressX = Note{
|
||||||
|
Name: "tun-address-x",
|
||||||
|
Description: "legacy tun address fields",
|
||||||
|
DeprecatedVersion: "1.10.0",
|
||||||
|
ScheduledVersion: "1.12.0",
|
||||||
|
MigrationLink: "https://sing-box.sagernet.org/migration/#tun-address-fields-are-merged",
|
||||||
|
}
|
||||||
|
|
||||||
|
var Options = []Note{
|
||||||
|
OptionBadMatchSource,
|
||||||
|
OptionGEOIP,
|
||||||
|
OptionGEOSITE,
|
||||||
|
OptionTUNAddressX,
|
||||||
|
}
|
30
experimental/deprecated/env.go
Normal file
30
experimental/deprecated/env.go
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
package deprecated
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/sagernet/sing/common/logger"
|
||||||
|
)
|
||||||
|
|
||||||
|
type envManager struct {
|
||||||
|
logger logger.Logger
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewEnvManager(logger logger.Logger) Manager {
|
||||||
|
return &envManager{logger: logger}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *envManager) ReportDeprecated(feature Note) {
|
||||||
|
if !feature.Impending() {
|
||||||
|
f.logger.Warn(feature.MessageWithLink())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
enable, enableErr := strconv.ParseBool(os.Getenv("ENABLE_DEPRECATED_" + feature.EnvName))
|
||||||
|
if enableErr == nil && enable {
|
||||||
|
f.logger.Warn(feature.MessageWithLink())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
f.logger.Error(feature.MessageWithLink())
|
||||||
|
f.logger.Fatal("to continuing using this feature, set ENABLE_DEPRECATED_" + feature.EnvName + "=true")
|
||||||
|
}
|
19
experimental/deprecated/manager.go
Normal file
19
experimental/deprecated/manager.go
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
package deprecated
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/sagernet/sing/service"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Manager interface {
|
||||||
|
ReportDeprecated(feature Note)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Report(ctx context.Context, feature Note) {
|
||||||
|
manager := service.FromContext[Manager](ctx)
|
||||||
|
if manager == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
manager.ReportDeprecated(feature)
|
||||||
|
}
|
|
@ -16,4 +16,5 @@ const (
|
||||||
CommandSetSystemProxyEnabled
|
CommandSetSystemProxyEnabled
|
||||||
CommandConnections
|
CommandConnections
|
||||||
CommandCloseConnection
|
CommandCloseConnection
|
||||||
|
CommandGetDeprecatedNotes
|
||||||
)
|
)
|
||||||
|
|
|
@ -18,6 +18,10 @@ func (c *CommandClient) CloseConnection(connId string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
|
err = binary.Write(conn, binary.BigEndian, uint8(CommandCloseConnection))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
writer := bufio.NewWriter(conn)
|
writer := bufio.NewWriter(conn)
|
||||||
err = varbin.Write(writer, binary.BigEndian, connId)
|
err = varbin.Write(writer, binary.BigEndian, connId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
46
experimental/libbox/command_deprecated_report.go
Normal file
46
experimental/libbox/command_deprecated_report.go
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
package libbox
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"net"
|
||||||
|
|
||||||
|
"github.com/sagernet/sing-box/experimental/deprecated"
|
||||||
|
"github.com/sagernet/sing/common"
|
||||||
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
|
"github.com/sagernet/sing/common/varbin"
|
||||||
|
"github.com/sagernet/sing/service"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (c *CommandClient) GetDeprecatedNotes() (DeprecatedNoteIterator, error) {
|
||||||
|
conn, err := c.directConnect()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer conn.Close()
|
||||||
|
err = binary.Write(conn, binary.BigEndian, uint8(CommandGetDeprecatedNotes))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
err = readError(conn)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var features []deprecated.Note
|
||||||
|
err = varbin.Read(conn, binary.BigEndian, &features)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return newIterator(common.Map(features, func(it deprecated.Note) *DeprecatedNote { return (*DeprecatedNote)(&it) })), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *CommandServer) handleGetDeprecatedNotes(conn net.Conn) error {
|
||||||
|
boxService := s.service
|
||||||
|
if boxService == nil {
|
||||||
|
return writeError(conn, E.New("service not ready"))
|
||||||
|
}
|
||||||
|
err := writeError(conn, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return varbin.Write(conn, binary.BigEndian, service.FromContext[deprecated.Manager](boxService.ctx).(*deprecatedManager).Get())
|
||||||
|
}
|
|
@ -174,6 +174,8 @@ func (s *CommandServer) handleConnection(conn net.Conn) error {
|
||||||
return s.handleConnectionsConn(conn)
|
return s.handleConnectionsConn(conn)
|
||||||
case CommandCloseConnection:
|
case CommandCloseConnection:
|
||||||
return s.handleCloseConnection(conn)
|
return s.handleCloseConnection(conn)
|
||||||
|
case CommandGetDeprecatedNotes:
|
||||||
|
return s.handleGetDeprecatedNotes(conn)
|
||||||
default:
|
default:
|
||||||
return E.New("unknown command: ", command)
|
return E.New("unknown command: ", command)
|
||||||
}
|
}
|
||||||
|
|
56
experimental/libbox/deprecated.go
Normal file
56
experimental/libbox/deprecated.go
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
package libbox
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/sagernet/sing-box/experimental/deprecated"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ deprecated.Manager = (*deprecatedManager)(nil)
|
||||||
|
|
||||||
|
type deprecatedManager struct {
|
||||||
|
access sync.Mutex
|
||||||
|
features []deprecated.Note
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *deprecatedManager) ReportDeprecated(feature deprecated.Note) {
|
||||||
|
m.access.Lock()
|
||||||
|
defer m.access.Unlock()
|
||||||
|
m.features = append(m.features, feature)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *deprecatedManager) Get() []deprecated.Note {
|
||||||
|
m.access.Lock()
|
||||||
|
defer m.access.Unlock()
|
||||||
|
features := m.features
|
||||||
|
m.features = nil
|
||||||
|
return features
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ = deprecated.Note(DeprecatedNote{})
|
||||||
|
|
||||||
|
type DeprecatedNote struct {
|
||||||
|
Name string
|
||||||
|
Description string
|
||||||
|
DeprecatedVersion string
|
||||||
|
ScheduledVersion string
|
||||||
|
EnvName string
|
||||||
|
MigrationLink string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n DeprecatedNote) Impending() bool {
|
||||||
|
return deprecated.Note(n).Impending()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n DeprecatedNote) Message() string {
|
||||||
|
return deprecated.Note(n).Message()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n DeprecatedNote) MessageWithLink() string {
|
||||||
|
return deprecated.Note(n).MessageWithLink()
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeprecatedNoteIterator interface {
|
||||||
|
HasNext() bool
|
||||||
|
Next() *DeprecatedNote
|
||||||
|
}
|
|
@ -14,6 +14,7 @@ import (
|
||||||
"github.com/sagernet/sing-box/common/process"
|
"github.com/sagernet/sing-box/common/process"
|
||||||
"github.com/sagernet/sing-box/common/urltest"
|
"github.com/sagernet/sing-box/common/urltest"
|
||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
|
"github.com/sagernet/sing-box/experimental/deprecated"
|
||||||
"github.com/sagernet/sing-box/experimental/libbox/internal/procfs"
|
"github.com/sagernet/sing-box/experimental/libbox/internal/procfs"
|
||||||
"github.com/sagernet/sing-box/experimental/libbox/platform"
|
"github.com/sagernet/sing-box/experimental/libbox/platform"
|
||||||
"github.com/sagernet/sing-box/log"
|
"github.com/sagernet/sing-box/log"
|
||||||
|
@ -49,6 +50,7 @@ func NewService(configContent string, platformInterface PlatformInterface) (*Box
|
||||||
ctx = filemanager.WithDefault(ctx, sWorkingPath, sTempPath, sUserID, sGroupID)
|
ctx = filemanager.WithDefault(ctx, sWorkingPath, sTempPath, sUserID, sGroupID)
|
||||||
urlTestHistoryStorage := urltest.NewHistoryStorage()
|
urlTestHistoryStorage := urltest.NewHistoryStorage()
|
||||||
ctx = service.ContextWithPtr(ctx, urlTestHistoryStorage)
|
ctx = service.ContextWithPtr(ctx, urlTestHistoryStorage)
|
||||||
|
ctx = service.ContextWith[deprecated.Manager](ctx, new(deprecatedManager))
|
||||||
platformWrapper := &platformInterfaceWrapper{iif: platformInterface, useProcFS: platformInterface.UseProcFS()}
|
platformWrapper := &platformInterfaceWrapper{iif: platformInterface, useProcFS: platformInterface.UseProcFS()}
|
||||||
instance, err := box.New(box.Options{
|
instance, err := box.New(box.Options{
|
||||||
Context: ctx,
|
Context: ctx,
|
||||||
|
|
2
go.mod
2
go.mod
|
@ -46,6 +46,7 @@ require (
|
||||||
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba
|
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba
|
||||||
golang.org/x/crypto v0.25.0
|
golang.org/x/crypto v0.25.0
|
||||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56
|
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56
|
||||||
|
golang.org/x/mod v0.19.0
|
||||||
golang.org/x/net v0.27.0
|
golang.org/x/net v0.27.0
|
||||||
golang.org/x/sys v0.25.0
|
golang.org/x/sys v0.25.0
|
||||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6
|
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6
|
||||||
|
@ -89,7 +90,6 @@ require (
|
||||||
github.com/vishvananda/netns v0.0.4 // indirect
|
github.com/vishvananda/netns v0.0.4 // indirect
|
||||||
github.com/zeebo/blake3 v0.2.3 // indirect
|
github.com/zeebo/blake3 v0.2.3 // indirect
|
||||||
go.uber.org/multierr v1.11.0 // indirect
|
go.uber.org/multierr v1.11.0 // indirect
|
||||||
golang.org/x/mod v0.19.0 // indirect
|
|
||||||
golang.org/x/sync v0.8.0 // indirect
|
golang.org/x/sync v0.8.0 // indirect
|
||||||
golang.org/x/text v0.18.0 // indirect
|
golang.org/x/text v0.18.0 // indirect
|
||||||
golang.org/x/time v0.5.0 // indirect
|
golang.org/x/time v0.5.0 // indirect
|
||||||
|
|
|
@ -13,6 +13,7 @@ import (
|
||||||
"github.com/sagernet/sing-box/adapter"
|
"github.com/sagernet/sing-box/adapter"
|
||||||
"github.com/sagernet/sing-box/common/taskmonitor"
|
"github.com/sagernet/sing-box/common/taskmonitor"
|
||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
|
"github.com/sagernet/sing-box/experimental/deprecated"
|
||||||
"github.com/sagernet/sing-box/experimental/libbox/platform"
|
"github.com/sagernet/sing-box/experimental/libbox/platform"
|
||||||
"github.com/sagernet/sing-box/log"
|
"github.com/sagernet/sing-box/log"
|
||||||
"github.com/sagernet/sing-box/option"
|
"github.com/sagernet/sing-box/option"
|
||||||
|
@ -54,15 +55,18 @@ type Tun struct {
|
||||||
|
|
||||||
func NewTun(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.TunInboundOptions, platformInterface platform.Interface) (*Tun, error) {
|
func NewTun(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.TunInboundOptions, platformInterface platform.Interface) (*Tun, error) {
|
||||||
address := options.Address
|
address := options.Address
|
||||||
|
var deprecatedAddressUsed bool
|
||||||
//nolint:staticcheck
|
//nolint:staticcheck
|
||||||
//goland:noinspection GoDeprecation
|
//goland:noinspection GoDeprecation
|
||||||
if len(options.Inet4Address) > 0 {
|
if len(options.Inet4Address) > 0 {
|
||||||
address = append(address, options.Inet4Address...)
|
address = append(address, options.Inet4Address...)
|
||||||
|
deprecatedAddressUsed = true
|
||||||
}
|
}
|
||||||
//nolint:staticcheck
|
//nolint:staticcheck
|
||||||
//goland:noinspection GoDeprecation
|
//goland:noinspection GoDeprecation
|
||||||
if len(options.Inet6Address) > 0 {
|
if len(options.Inet6Address) > 0 {
|
||||||
address = append(address, options.Inet6Address...)
|
address = append(address, options.Inet6Address...)
|
||||||
|
deprecatedAddressUsed = true
|
||||||
}
|
}
|
||||||
inet4Address := common.Filter(address, func(it netip.Prefix) bool {
|
inet4Address := common.Filter(address, func(it netip.Prefix) bool {
|
||||||
return it.Addr().Is4()
|
return it.Addr().Is4()
|
||||||
|
@ -76,11 +80,13 @@ func NewTun(ctx context.Context, router adapter.Router, logger log.ContextLogger
|
||||||
//goland:noinspection GoDeprecation
|
//goland:noinspection GoDeprecation
|
||||||
if len(options.Inet4RouteAddress) > 0 {
|
if len(options.Inet4RouteAddress) > 0 {
|
||||||
routeAddress = append(routeAddress, options.Inet4RouteAddress...)
|
routeAddress = append(routeAddress, options.Inet4RouteAddress...)
|
||||||
|
deprecatedAddressUsed = true
|
||||||
}
|
}
|
||||||
//nolint:staticcheck
|
//nolint:staticcheck
|
||||||
//goland:noinspection GoDeprecation
|
//goland:noinspection GoDeprecation
|
||||||
if len(options.Inet6RouteAddress) > 0 {
|
if len(options.Inet6RouteAddress) > 0 {
|
||||||
routeAddress = append(routeAddress, options.Inet6RouteAddress...)
|
routeAddress = append(routeAddress, options.Inet6RouteAddress...)
|
||||||
|
deprecatedAddressUsed = true
|
||||||
}
|
}
|
||||||
inet4RouteAddress := common.Filter(routeAddress, func(it netip.Prefix) bool {
|
inet4RouteAddress := common.Filter(routeAddress, func(it netip.Prefix) bool {
|
||||||
return it.Addr().Is4()
|
return it.Addr().Is4()
|
||||||
|
@ -94,11 +100,13 @@ func NewTun(ctx context.Context, router adapter.Router, logger log.ContextLogger
|
||||||
//goland:noinspection GoDeprecation
|
//goland:noinspection GoDeprecation
|
||||||
if len(options.Inet4RouteExcludeAddress) > 0 {
|
if len(options.Inet4RouteExcludeAddress) > 0 {
|
||||||
routeExcludeAddress = append(routeExcludeAddress, options.Inet4RouteExcludeAddress...)
|
routeExcludeAddress = append(routeExcludeAddress, options.Inet4RouteExcludeAddress...)
|
||||||
|
deprecatedAddressUsed = true
|
||||||
}
|
}
|
||||||
//nolint:staticcheck
|
//nolint:staticcheck
|
||||||
//goland:noinspection GoDeprecation
|
//goland:noinspection GoDeprecation
|
||||||
if len(options.Inet6RouteExcludeAddress) > 0 {
|
if len(options.Inet6RouteExcludeAddress) > 0 {
|
||||||
routeExcludeAddress = append(routeExcludeAddress, options.Inet6RouteExcludeAddress...)
|
routeExcludeAddress = append(routeExcludeAddress, options.Inet6RouteExcludeAddress...)
|
||||||
|
deprecatedAddressUsed = true
|
||||||
}
|
}
|
||||||
inet4RouteExcludeAddress := common.Filter(routeExcludeAddress, func(it netip.Prefix) bool {
|
inet4RouteExcludeAddress := common.Filter(routeExcludeAddress, func(it netip.Prefix) bool {
|
||||||
return it.Addr().Is4()
|
return it.Addr().Is4()
|
||||||
|
@ -107,6 +115,10 @@ func NewTun(ctx context.Context, router adapter.Router, logger log.ContextLogger
|
||||||
return it.Addr().Is6()
|
return it.Addr().Is6()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if deprecatedAddressUsed {
|
||||||
|
deprecated.Report(ctx, deprecated.OptionTUNAddressX)
|
||||||
|
}
|
||||||
|
|
||||||
tunMTU := options.MTU
|
tunMTU := options.MTU
|
||||||
if tunMTU == 0 {
|
if tunMTU == 0 {
|
||||||
tunMTU = 9000
|
tunMTU = 9000
|
||||||
|
|
|
@ -64,7 +64,7 @@ func (r Rule) IsValid() bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type _DefaultRule struct {
|
type DefaultRule struct {
|
||||||
Inbound Listable[string] `json:"inbound,omitempty"`
|
Inbound Listable[string] `json:"inbound,omitempty"`
|
||||||
IPVersion int `json:"ip_version,omitempty"`
|
IPVersion int `json:"ip_version,omitempty"`
|
||||||
Network Listable[string] `json:"network,omitempty"`
|
Network Listable[string] `json:"network,omitempty"`
|
||||||
|
@ -104,22 +104,6 @@ type _DefaultRule struct {
|
||||||
Deprecated_RulesetIPCIDRMatchSource bool `json:"rule_set_ipcidr_match_source,omitempty"`
|
Deprecated_RulesetIPCIDRMatchSource bool `json:"rule_set_ipcidr_match_source,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type DefaultRule _DefaultRule
|
|
||||||
|
|
||||||
func (r *DefaultRule) UnmarshalJSON(bytes []byte) error {
|
|
||||||
err := json.Unmarshal(bytes, (*_DefaultRule)(r))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
//nolint:staticcheck
|
|
||||||
//goland:noinspection GoDeprecation
|
|
||||||
if r.Deprecated_RulesetIPCIDRMatchSource {
|
|
||||||
r.Deprecated_RulesetIPCIDRMatchSource = false
|
|
||||||
r.RuleSetIPCIDRMatchSource = true
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *DefaultRule) IsValid() bool {
|
func (r *DefaultRule) IsValid() bool {
|
||||||
var defaultValue DefaultRule
|
var defaultValue DefaultRule
|
||||||
defaultValue.Invert = r.Invert
|
defaultValue.Invert = r.Invert
|
||||||
|
|
|
@ -64,7 +64,7 @@ func (r DNSRule) IsValid() bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type _DefaultDNSRule struct {
|
type DefaultDNSRule struct {
|
||||||
Inbound Listable[string] `json:"inbound,omitempty"`
|
Inbound Listable[string] `json:"inbound,omitempty"`
|
||||||
IPVersion int `json:"ip_version,omitempty"`
|
IPVersion int `json:"ip_version,omitempty"`
|
||||||
QueryType Listable[DNSQueryType] `json:"query_type,omitempty"`
|
QueryType Listable[DNSQueryType] `json:"query_type,omitempty"`
|
||||||
|
@ -109,22 +109,6 @@ type _DefaultDNSRule struct {
|
||||||
Deprecated_RulesetIPCIDRMatchSource bool `json:"rule_set_ipcidr_match_source,omitempty"`
|
Deprecated_RulesetIPCIDRMatchSource bool `json:"rule_set_ipcidr_match_source,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type DefaultDNSRule _DefaultDNSRule
|
|
||||||
|
|
||||||
func (r *DefaultDNSRule) UnmarshalJSON(bytes []byte) error {
|
|
||||||
err := json.UnmarshalDisallowUnknownFields(bytes, (*_DefaultDNSRule)(r))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
//nolint:staticcheck
|
|
||||||
//goland:noinspection GoDeprecation
|
|
||||||
if r.Deprecated_RulesetIPCIDRMatchSource {
|
|
||||||
r.Deprecated_RulesetIPCIDRMatchSource = false
|
|
||||||
r.RuleSetIPCIDRMatchSource = true
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *DefaultDNSRule) IsValid() bool {
|
func (r *DefaultDNSRule) IsValid() bool {
|
||||||
var defaultValue DefaultDNSRule
|
var defaultValue DefaultDNSRule
|
||||||
defaultValue.Invert = r.Invert
|
defaultValue.Invert = r.Invert
|
||||||
|
|
|
@ -153,14 +153,14 @@ func NewRouter(
|
||||||
Logger: router.dnsLogger,
|
Logger: router.dnsLogger,
|
||||||
})
|
})
|
||||||
for i, ruleOptions := range options.Rules {
|
for i, ruleOptions := range options.Rules {
|
||||||
routeRule, err := NewRule(router, router.logger, ruleOptions, true)
|
routeRule, err := NewRule(ctx, router, router.logger, ruleOptions, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, E.Cause(err, "parse rule[", i, "]")
|
return nil, E.Cause(err, "parse rule[", i, "]")
|
||||||
}
|
}
|
||||||
router.rules = append(router.rules, routeRule)
|
router.rules = append(router.rules, routeRule)
|
||||||
}
|
}
|
||||||
for i, dnsRuleOptions := range dnsOptions.Rules {
|
for i, dnsRuleOptions := range dnsOptions.Rules {
|
||||||
dnsRule, err := NewDNSRule(router, router.logger, dnsRuleOptions, true)
|
dnsRule, err := NewDNSRule(ctx, router, router.logger, dnsRuleOptions, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, E.Cause(err, "parse dns rule[", i, "]")
|
return nil, E.Cause(err, "parse dns rule[", i, "]")
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"github.com/sagernet/sing-box/common/geoip"
|
"github.com/sagernet/sing-box/common/geoip"
|
||||||
"github.com/sagernet/sing-box/common/geosite"
|
"github.com/sagernet/sing-box/common/geosite"
|
||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
|
"github.com/sagernet/sing-box/experimental/deprecated"
|
||||||
E "github.com/sagernet/sing/common/exceptions"
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
M "github.com/sagernet/sing/common/metadata"
|
M "github.com/sagernet/sing/common/metadata"
|
||||||
"github.com/sagernet/sing/common/rw"
|
"github.com/sagernet/sing/common/rw"
|
||||||
|
@ -31,7 +32,7 @@ func (r *Router) LoadGeosite(code string) (adapter.Rule, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
rule, err = NewDefaultRule(r, nil, geosite.Compile(items))
|
rule, err = NewDefaultRule(r.ctx, r, nil, geosite.Compile(items))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -40,6 +41,7 @@ func (r *Router) LoadGeosite(code string) (adapter.Rule, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Router) prepareGeoIPDatabase() error {
|
func (r *Router) prepareGeoIPDatabase() error {
|
||||||
|
deprecated.Report(r.ctx, deprecated.OptionGEOIP)
|
||||||
var geoPath string
|
var geoPath string
|
||||||
if r.geoIPOptions.Path != "" {
|
if r.geoIPOptions.Path != "" {
|
||||||
geoPath = r.geoIPOptions.Path
|
geoPath = r.geoIPOptions.Path
|
||||||
|
@ -86,6 +88,7 @@ func (r *Router) prepareGeoIPDatabase() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Router) prepareGeositeDatabase() error {
|
func (r *Router) prepareGeositeDatabase() error {
|
||||||
|
deprecated.Report(r.ctx, deprecated.OptionGEOSITE)
|
||||||
var geoPath string
|
var geoPath string
|
||||||
if r.geositeOptions.Path != "" {
|
if r.geositeOptions.Path != "" {
|
||||||
geoPath = r.geositeOptions.Path
|
geoPath = r.geositeOptions.Path
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
package route
|
package route
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
"github.com/sagernet/sing-box/adapter"
|
"github.com/sagernet/sing-box/adapter"
|
||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
|
"github.com/sagernet/sing-box/experimental/deprecated"
|
||||||
"github.com/sagernet/sing-box/log"
|
"github.com/sagernet/sing-box/log"
|
||||||
"github.com/sagernet/sing-box/option"
|
"github.com/sagernet/sing-box/option"
|
||||||
E "github.com/sagernet/sing/common/exceptions"
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewRule(router adapter.Router, logger log.ContextLogger, options option.Rule, checkOutbound bool) (adapter.Rule, error) {
|
func NewRule(ctx context.Context, router adapter.Router, logger log.ContextLogger, options option.Rule, checkOutbound bool) (adapter.Rule, error) {
|
||||||
switch options.Type {
|
switch options.Type {
|
||||||
case "", C.RuleTypeDefault:
|
case "", C.RuleTypeDefault:
|
||||||
if !options.DefaultOptions.IsValid() {
|
if !options.DefaultOptions.IsValid() {
|
||||||
|
@ -17,7 +20,7 @@ func NewRule(router adapter.Router, logger log.ContextLogger, options option.Rul
|
||||||
if options.DefaultOptions.Outbound == "" && checkOutbound {
|
if options.DefaultOptions.Outbound == "" && checkOutbound {
|
||||||
return nil, E.New("missing outbound field")
|
return nil, E.New("missing outbound field")
|
||||||
}
|
}
|
||||||
return NewDefaultRule(router, logger, options.DefaultOptions)
|
return NewDefaultRule(ctx, router, logger, options.DefaultOptions)
|
||||||
case C.RuleTypeLogical:
|
case C.RuleTypeLogical:
|
||||||
if !options.LogicalOptions.IsValid() {
|
if !options.LogicalOptions.IsValid() {
|
||||||
return nil, E.New("missing conditions")
|
return nil, E.New("missing conditions")
|
||||||
|
@ -25,7 +28,7 @@ func NewRule(router adapter.Router, logger log.ContextLogger, options option.Rul
|
||||||
if options.LogicalOptions.Outbound == "" && checkOutbound {
|
if options.LogicalOptions.Outbound == "" && checkOutbound {
|
||||||
return nil, E.New("missing outbound field")
|
return nil, E.New("missing outbound field")
|
||||||
}
|
}
|
||||||
return NewLogicalRule(router, logger, options.LogicalOptions)
|
return NewLogicalRule(ctx, router, logger, options.LogicalOptions)
|
||||||
default:
|
default:
|
||||||
return nil, E.New("unknown rule type: ", options.Type)
|
return nil, E.New("unknown rule type: ", options.Type)
|
||||||
}
|
}
|
||||||
|
@ -42,7 +45,7 @@ type RuleItem interface {
|
||||||
String() string
|
String() string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDefaultRule(router adapter.Router, logger log.ContextLogger, options option.DefaultRule) (*DefaultRule, error) {
|
func NewDefaultRule(ctx context.Context, router adapter.Router, logger log.ContextLogger, options option.DefaultRule) (*DefaultRule, error) {
|
||||||
rule := &DefaultRule{
|
rule := &DefaultRule{
|
||||||
abstractDefaultRule{
|
abstractDefaultRule{
|
||||||
invert: options.Invert,
|
invert: options.Invert,
|
||||||
|
@ -218,7 +221,16 @@ func NewDefaultRule(router adapter.Router, logger log.ContextLogger, options opt
|
||||||
rule.allItems = append(rule.allItems, item)
|
rule.allItems = append(rule.allItems, item)
|
||||||
}
|
}
|
||||||
if len(options.RuleSet) > 0 {
|
if len(options.RuleSet) > 0 {
|
||||||
item := NewRuleSetItem(router, options.RuleSet, options.RuleSetIPCIDRMatchSource, false)
|
var matchSource bool
|
||||||
|
if options.RuleSetIPCIDRMatchSource {
|
||||||
|
matchSource = true
|
||||||
|
} else
|
||||||
|
//nolint:staticcheck
|
||||||
|
if options.Deprecated_RulesetIPCIDRMatchSource {
|
||||||
|
matchSource = true
|
||||||
|
deprecated.Report(ctx, deprecated.OptionBadMatchSource)
|
||||||
|
}
|
||||||
|
item := NewRuleSetItem(router, options.RuleSet, matchSource, false)
|
||||||
rule.items = append(rule.items, item)
|
rule.items = append(rule.items, item)
|
||||||
rule.allItems = append(rule.allItems, item)
|
rule.allItems = append(rule.allItems, item)
|
||||||
}
|
}
|
||||||
|
@ -231,7 +243,7 @@ type LogicalRule struct {
|
||||||
abstractLogicalRule
|
abstractLogicalRule
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewLogicalRule(router adapter.Router, logger log.ContextLogger, options option.LogicalRule) (*LogicalRule, error) {
|
func NewLogicalRule(ctx context.Context, router adapter.Router, logger log.ContextLogger, options option.LogicalRule) (*LogicalRule, error) {
|
||||||
r := &LogicalRule{
|
r := &LogicalRule{
|
||||||
abstractLogicalRule{
|
abstractLogicalRule{
|
||||||
rules: make([]adapter.HeadlessRule, len(options.Rules)),
|
rules: make([]adapter.HeadlessRule, len(options.Rules)),
|
||||||
|
@ -248,7 +260,7 @@ func NewLogicalRule(router adapter.Router, logger log.ContextLogger, options opt
|
||||||
return nil, E.New("unknown logical mode: ", options.Mode)
|
return nil, E.New("unknown logical mode: ", options.Mode)
|
||||||
}
|
}
|
||||||
for i, subRule := range options.Rules {
|
for i, subRule := range options.Rules {
|
||||||
rule, err := NewRule(router, logger, subRule, false)
|
rule, err := NewRule(ctx, router, logger, subRule, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, E.Cause(err, "sub rule[", i, "]")
|
return nil, E.Cause(err, "sub rule[", i, "]")
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,19 @@
|
||||||
package route
|
package route
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
|
|
||||||
"github.com/sagernet/sing-box/adapter"
|
"github.com/sagernet/sing-box/adapter"
|
||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
|
"github.com/sagernet/sing-box/experimental/deprecated"
|
||||||
"github.com/sagernet/sing-box/log"
|
"github.com/sagernet/sing-box/log"
|
||||||
"github.com/sagernet/sing-box/option"
|
"github.com/sagernet/sing-box/option"
|
||||||
"github.com/sagernet/sing/common"
|
"github.com/sagernet/sing/common"
|
||||||
E "github.com/sagernet/sing/common/exceptions"
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewDNSRule(router adapter.Router, logger log.ContextLogger, options option.DNSRule, checkServer bool) (adapter.DNSRule, error) {
|
func NewDNSRule(ctx context.Context, router adapter.Router, logger log.ContextLogger, options option.DNSRule, checkServer bool) (adapter.DNSRule, error) {
|
||||||
switch options.Type {
|
switch options.Type {
|
||||||
case "", C.RuleTypeDefault:
|
case "", C.RuleTypeDefault:
|
||||||
if !options.DefaultOptions.IsValid() {
|
if !options.DefaultOptions.IsValid() {
|
||||||
|
@ -20,7 +22,7 @@ func NewDNSRule(router adapter.Router, logger log.ContextLogger, options option.
|
||||||
if options.DefaultOptions.Server == "" && checkServer {
|
if options.DefaultOptions.Server == "" && checkServer {
|
||||||
return nil, E.New("missing server field")
|
return nil, E.New("missing server field")
|
||||||
}
|
}
|
||||||
return NewDefaultDNSRule(router, logger, options.DefaultOptions)
|
return NewDefaultDNSRule(ctx, router, logger, options.DefaultOptions)
|
||||||
case C.RuleTypeLogical:
|
case C.RuleTypeLogical:
|
||||||
if !options.LogicalOptions.IsValid() {
|
if !options.LogicalOptions.IsValid() {
|
||||||
return nil, E.New("missing conditions")
|
return nil, E.New("missing conditions")
|
||||||
|
@ -28,7 +30,7 @@ func NewDNSRule(router adapter.Router, logger log.ContextLogger, options option.
|
||||||
if options.LogicalOptions.Server == "" && checkServer {
|
if options.LogicalOptions.Server == "" && checkServer {
|
||||||
return nil, E.New("missing server field")
|
return nil, E.New("missing server field")
|
||||||
}
|
}
|
||||||
return NewLogicalDNSRule(router, logger, options.LogicalOptions)
|
return NewLogicalDNSRule(ctx, router, logger, options.LogicalOptions)
|
||||||
default:
|
default:
|
||||||
return nil, E.New("unknown rule type: ", options.Type)
|
return nil, E.New("unknown rule type: ", options.Type)
|
||||||
}
|
}
|
||||||
|
@ -43,7 +45,7 @@ type DefaultDNSRule struct {
|
||||||
clientSubnet *netip.Prefix
|
clientSubnet *netip.Prefix
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDefaultDNSRule(router adapter.Router, logger log.ContextLogger, options option.DefaultDNSRule) (*DefaultDNSRule, error) {
|
func NewDefaultDNSRule(ctx context.Context, router adapter.Router, logger log.ContextLogger, options option.DefaultDNSRule) (*DefaultDNSRule, error) {
|
||||||
rule := &DefaultDNSRule{
|
rule := &DefaultDNSRule{
|
||||||
abstractDefaultRule: abstractDefaultRule{
|
abstractDefaultRule: abstractDefaultRule{
|
||||||
invert: options.Invert,
|
invert: options.Invert,
|
||||||
|
@ -227,7 +229,16 @@ func NewDefaultDNSRule(router adapter.Router, logger log.ContextLogger, options
|
||||||
rule.allItems = append(rule.allItems, item)
|
rule.allItems = append(rule.allItems, item)
|
||||||
}
|
}
|
||||||
if len(options.RuleSet) > 0 {
|
if len(options.RuleSet) > 0 {
|
||||||
item := NewRuleSetItem(router, options.RuleSet, options.RuleSetIPCIDRMatchSource, options.RuleSetIPCIDRAcceptEmpty)
|
var matchSource bool
|
||||||
|
if options.RuleSetIPCIDRMatchSource {
|
||||||
|
matchSource = true
|
||||||
|
} else
|
||||||
|
//nolint:staticcheck
|
||||||
|
if options.Deprecated_RulesetIPCIDRMatchSource {
|
||||||
|
matchSource = true
|
||||||
|
deprecated.Report(ctx, deprecated.OptionBadMatchSource)
|
||||||
|
}
|
||||||
|
item := NewRuleSetItem(router, options.RuleSet, matchSource, options.RuleSetIPCIDRAcceptEmpty)
|
||||||
rule.items = append(rule.items, item)
|
rule.items = append(rule.items, item)
|
||||||
rule.allItems = append(rule.allItems, item)
|
rule.allItems = append(rule.allItems, item)
|
||||||
}
|
}
|
||||||
|
@ -283,7 +294,7 @@ type LogicalDNSRule struct {
|
||||||
clientSubnet *netip.Prefix
|
clientSubnet *netip.Prefix
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewLogicalDNSRule(router adapter.Router, logger log.ContextLogger, options option.LogicalDNSRule) (*LogicalDNSRule, error) {
|
func NewLogicalDNSRule(ctx context.Context, router adapter.Router, logger log.ContextLogger, options option.LogicalDNSRule) (*LogicalDNSRule, error) {
|
||||||
r := &LogicalDNSRule{
|
r := &LogicalDNSRule{
|
||||||
abstractLogicalRule: abstractLogicalRule{
|
abstractLogicalRule: abstractLogicalRule{
|
||||||
rules: make([]adapter.HeadlessRule, len(options.Rules)),
|
rules: make([]adapter.HeadlessRule, len(options.Rules)),
|
||||||
|
@ -303,7 +314,7 @@ func NewLogicalDNSRule(router adapter.Router, logger log.ContextLogger, options
|
||||||
return nil, E.New("unknown logical mode: ", options.Mode)
|
return nil, E.New("unknown logical mode: ", options.Mode)
|
||||||
}
|
}
|
||||||
for i, subRule := range options.Rules {
|
for i, subRule := range options.Rules {
|
||||||
rule, err := NewDNSRule(router, logger, subRule, false)
|
rule, err := NewDNSRule(ctx, router, logger, subRule, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, E.Cause(err, "sub rule[", i, "]")
|
return nil, E.Cause(err, "sub rule[", i, "]")
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue