github.com/sagernet/sing-box@v1.9.0-rc.20/experimental/libbox/config.go (about) 1 package libbox 2 3 import ( 4 "bytes" 5 "context" 6 "net/netip" 7 "os" 8 9 "github.com/sagernet/sing-box" 10 "github.com/sagernet/sing-box/adapter" 11 "github.com/sagernet/sing-box/common/process" 12 "github.com/sagernet/sing-box/option" 13 "github.com/sagernet/sing-tun" 14 "github.com/sagernet/sing/common/control" 15 E "github.com/sagernet/sing/common/exceptions" 16 "github.com/sagernet/sing/common/json" 17 "github.com/sagernet/sing/common/logger" 18 "github.com/sagernet/sing/common/x/list" 19 ) 20 21 func parseConfig(configContent string) (option.Options, error) { 22 options, err := json.UnmarshalExtended[option.Options]([]byte(configContent)) 23 if err != nil { 24 return option.Options{}, E.Cause(err, "decode config") 25 } 26 return options, nil 27 } 28 29 func CheckConfig(configContent string) error { 30 options, err := parseConfig(configContent) 31 if err != nil { 32 return err 33 } 34 ctx, cancel := context.WithCancel(context.Background()) 35 defer cancel() 36 instance, err := box.New(box.Options{ 37 Context: ctx, 38 Options: options, 39 PlatformInterface: (*platformInterfaceStub)(nil), 40 }) 41 if err == nil { 42 instance.Close() 43 } 44 return err 45 } 46 47 type platformInterfaceStub struct{} 48 49 func (s *platformInterfaceStub) Initialize(ctx context.Context, router adapter.Router) error { 50 return nil 51 } 52 53 func (s *platformInterfaceStub) UsePlatformAutoDetectInterfaceControl() bool { 54 return true 55 } 56 57 func (s *platformInterfaceStub) AutoDetectInterfaceControl() control.Func { 58 return nil 59 } 60 61 func (s *platformInterfaceStub) OpenTun(options *tun.Options, platformOptions option.TunPlatformOptions) (tun.Tun, error) { 62 return nil, os.ErrInvalid 63 } 64 65 func (s *platformInterfaceStub) UsePlatformDefaultInterfaceMonitor() bool { 66 return true 67 } 68 69 func (s *platformInterfaceStub) CreateDefaultInterfaceMonitor(logger logger.Logger) tun.DefaultInterfaceMonitor { 70 return (*interfaceMonitorStub)(nil) 71 } 72 73 func (s *platformInterfaceStub) UsePlatformInterfaceGetter() bool { 74 return true 75 } 76 77 func (s *platformInterfaceStub) Interfaces() ([]control.Interface, error) { 78 return nil, os.ErrInvalid 79 } 80 81 func (s *platformInterfaceStub) UnderNetworkExtension() bool { 82 return false 83 } 84 85 func (s *platformInterfaceStub) IncludeAllNetworks() bool { 86 return false 87 } 88 89 func (s *platformInterfaceStub) ClearDNSCache() { 90 } 91 92 func (s *platformInterfaceStub) ReadWIFIState() adapter.WIFIState { 93 return adapter.WIFIState{} 94 } 95 96 func (s *platformInterfaceStub) FindProcessInfo(ctx context.Context, network string, source netip.AddrPort, destination netip.AddrPort) (*process.Info, error) { 97 return nil, os.ErrInvalid 98 } 99 100 type interfaceMonitorStub struct{} 101 102 func (s *interfaceMonitorStub) Start() error { 103 return os.ErrInvalid 104 } 105 106 func (s *interfaceMonitorStub) Close() error { 107 return os.ErrInvalid 108 } 109 110 func (s *interfaceMonitorStub) DefaultInterfaceName(destination netip.Addr) string { 111 return "" 112 } 113 114 func (s *interfaceMonitorStub) DefaultInterfaceIndex(destination netip.Addr) int { 115 return -1 116 } 117 118 func (s *interfaceMonitorStub) DefaultInterface(destination netip.Addr) (string, int) { 119 return "", -1 120 } 121 122 func (s *interfaceMonitorStub) OverrideAndroidVPN() bool { 123 return false 124 } 125 126 func (s *interfaceMonitorStub) AndroidVPNEnabled() bool { 127 return false 128 } 129 130 func (s *interfaceMonitorStub) RegisterCallback(callback tun.DefaultInterfaceUpdateCallback) *list.Element[tun.DefaultInterfaceUpdateCallback] { 131 return nil 132 } 133 134 func (s *interfaceMonitorStub) UnregisterCallback(element *list.Element[tun.DefaultInterfaceUpdateCallback]) { 135 } 136 137 func FormatConfig(configContent string) (string, error) { 138 options, err := parseConfig(configContent) 139 if err != nil { 140 return "", err 141 } 142 var buffer bytes.Buffer 143 encoder := json.NewEncoder(&buffer) 144 encoder.SetIndent("", " ") 145 err = encoder.Encode(options) 146 if err != nil { 147 return "", err 148 } 149 return buffer.String(), nil 150 }