Files
s-ui/core/main.go
T
Seva a721c85955 Bugfix: User can't change DNS Invaild Settings (#1042)
* Fix core restart panic on invalid DNS config

* Avoid nil instance race after core stop
2026-03-07 11:34:33 +01:00

109 lines
2.3 KiB
Go

package core
import (
"context"
"sync"
"github.com/alireza0/s-ui/logger"
sb "github.com/sagernet/sing-box"
"github.com/sagernet/sing-box/adapter"
_ "github.com/sagernet/sing-box/experimental/clashapi"
_ "github.com/sagernet/sing-box/experimental/v2rayapi"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
_ "github.com/sagernet/sing-box/transport/v2rayquic"
"github.com/sagernet/sing/service"
)
var (
globalCtx context.Context
inbound_manager adapter.InboundManager
outbound_manager adapter.OutboundManager
service_manager adapter.ServiceManager
endpoint_manager adapter.EndpointManager
router adapter.Router
statsTracker *StatsTracker
connTracker *ConnTracker
factory log.Factory
)
type Core struct {
mu sync.RWMutex
isRunning bool
instance *Box
}
func NewCore() *Core {
globalCtx = context.Background()
globalCtx = sb.Context(globalCtx, InboundRegistry(), OutboundRegistry(), EndpointRegistry(), DNSTransportRegistry(), ServiceRegistry())
return &Core{
isRunning: false,
instance: nil,
}
}
func (c *Core) GetCtx() context.Context {
return globalCtx
}
func (c *Core) GetInstance() *Box {
c.mu.RLock()
defer c.mu.RUnlock()
return c.instance
}
func (c *Core) Start(sbConfig []byte) error {
c.mu.Lock()
defer c.mu.Unlock()
var opt option.Options
err := opt.UnmarshalJSONContext(globalCtx, sbConfig)
if err != nil {
logger.Error("Unmarshal config err:", err.Error())
}
c.instance, err = NewBox(Options{
Context: globalCtx,
Options: opt,
})
if err != nil {
return err
}
err = c.instance.Start()
if err != nil {
c.instance = nil
return err
}
globalCtx = service.ContextWith(globalCtx, c)
inbound_manager = service.FromContext[adapter.InboundManager](globalCtx)
outbound_manager = service.FromContext[adapter.OutboundManager](globalCtx)
service_manager = service.FromContext[adapter.ServiceManager](globalCtx)
endpoint_manager = service.FromContext[adapter.EndpointManager](globalCtx)
router = service.FromContext[adapter.Router](globalCtx)
c.isRunning = true
return nil
}
func (c *Core) Stop() error {
c.mu.Lock()
defer c.mu.Unlock()
c.isRunning = false
if c.instance == nil {
return nil
}
err := c.instance.Close()
c.instance = nil
return err
}
func (c *Core) IsRunning() bool {
c.mu.RLock()
defer c.mu.RUnlock()
return c.isRunning
}