Remove unimplemented hot reload from managers

This commit is contained in:
世界
2026-10-09 12:36:03 +08:00
parent bff5acf292
commit a364ff4794
18 changed files with 65 additions and 448 deletions
+4 -52
View File
@@ -2,7 +2,6 @@ package certificate
import (
"context"
"os"
"sync"
"time"
@@ -10,7 +9,6 @@ import (
"github.com/sagernet/sing-box/common/taskmonitor"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
F "github.com/sagernet/sing/common/format"
)
@@ -48,7 +46,7 @@ func (m *Manager) Start(stage adapter.StartStage) error {
name := "certificate-provider/" + provider.Type() + "[" + provider.Tag() + "]"
m.logger.Trace(stage, " ", name)
startTime := time.Now()
err := adapter.LegacyStart(provider, stage)
err := provider.Start(stage)
if err != nil {
return E.Cause(err, stage, " ", name)
}
@@ -95,29 +93,6 @@ func (m *Manager) Get(tag string) (adapter.CertificateProviderService, bool) {
return provider, found
}
func (m *Manager) Remove(tag string) error {
m.access.Lock()
provider, found := m.providerByTag[tag]
if !found {
m.access.Unlock()
return os.ErrInvalid
}
delete(m.providerByTag, tag)
index := common.Index(m.providers, func(it adapter.CertificateProviderService) bool {
return it == provider
})
if index == -1 {
panic("invalid certificate provider index")
}
m.providers = append(m.providers[:index], m.providers[index+1:]...)
started := m.started
m.access.Unlock()
if started {
return provider.Close()
}
return nil
}
func (m *Manager) Create(ctx context.Context, logger log.ContextLogger, tag string, providerType string, options any) error {
provider, err := m.registry.Create(ctx, logger, tag, providerType, options)
if err != nil {
@@ -125,32 +100,9 @@ func (m *Manager) Create(ctx context.Context, logger log.ContextLogger, tag stri
}
m.access.Lock()
defer m.access.Unlock()
if m.started {
name := "certificate-provider/" + provider.Type() + "[" + provider.Tag() + "]"
for _, stage := range adapter.ListStartStages {
m.logger.Trace(stage, " ", name)
startTime := time.Now()
err = adapter.LegacyStart(provider, stage)
if err != nil {
return E.Cause(err, stage, " ", name)
}
m.logger.Trace(stage, " ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)")
}
}
if existsProvider, loaded := m.providerByTag[tag]; loaded {
if m.started {
err = existsProvider.Close()
if err != nil {
return E.Cause(err, "close certificate-provider/", existsProvider.Type(), "[", existsProvider.Tag(), "]")
}
}
existsIndex := common.Index(m.providers, func(it adapter.CertificateProviderService) bool {
return it == existsProvider
})
if existsIndex == -1 {
panic("invalid certificate provider index")
}
m.providers = append(m.providers[:existsIndex], m.providers[existsIndex+1:]...)
_, loaded := m.providerByTag[tag]
if loaded {
return E.New("duplicate certificate provider tag: ", tag)
}
m.providers = append(m.providers, provider)
m.providerByTag[tag] = provider
-1
View File
@@ -33,6 +33,5 @@ type CertificateProviderManager interface {
Lifecycle
CertificateProviders() []CertificateProviderService
Get(tag string) (CertificateProviderService, bool)
Remove(tag string) error
Create(ctx context.Context, logger log.ContextLogger, tag string, providerType string, options any) error
}
-1
View File
@@ -89,6 +89,5 @@ type DNSTransportManager interface {
Transport(tag string) (DNSTransport, bool)
Default() DNSTransport
FakeIP() FakeIPTransport
Remove(tag string) error
Create(ctx context.Context, logger log.ContextLogger, tag string, outboundType string, options any) error
}
-1
View File
@@ -23,6 +23,5 @@ type EndpointManager interface {
Lifecycle
Endpoints() []Endpoint
Get(tag string) (Endpoint, bool)
Remove(tag string) error
Create(ctx context.Context, router Router, logger log.ContextLogger, tag string, endpointType string, options any) error
}
+4 -51
View File
@@ -2,14 +2,12 @@ package endpoint
import (
"context"
"os"
"sync"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/taskmonitor"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
)
@@ -48,7 +46,7 @@ func (m *Manager) Start(stage adapter.StartStage) error {
for _, endpoint := range m.endpoints {
name := "endpoint/" + endpoint.Type() + "[" + endpoint.Tag() + "]"
done := adapter.LogElapsed(m.logger, stage, " ", name)
err := adapter.LegacyStart(endpoint, stage)
err := endpoint.Start(stage)
done()
if err != nil {
return E.Cause(err, stage, " ", name)
@@ -94,29 +92,6 @@ func (m *Manager) Get(tag string) (adapter.Endpoint, bool) {
return endpoint, found
}
func (m *Manager) Remove(tag string) error {
m.access.Lock()
endpoint, found := m.endpointByTag[tag]
if !found {
m.access.Unlock()
return os.ErrInvalid
}
delete(m.endpointByTag, tag)
index := common.Index(m.endpoints, func(it adapter.Endpoint) bool {
return it == endpoint
})
if index == -1 {
panic("invalid endpoint index")
}
m.endpoints = append(m.endpoints[:index], m.endpoints[index+1:]...)
started := m.started
m.access.Unlock()
if started {
return endpoint.Close()
}
return nil
}
func (m *Manager) Create(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, outboundType string, options any) error {
endpoint, err := m.registry.Create(ctx, router, logger, tag, outboundType, options)
if err != nil {
@@ -124,31 +99,9 @@ func (m *Manager) Create(ctx context.Context, router adapter.Router, logger log.
}
m.access.Lock()
defer m.access.Unlock()
if m.started {
name := "endpoint/" + endpoint.Type() + "[" + endpoint.Tag() + "]"
for _, stage := range adapter.ListStartStages {
done := adapter.LogElapsed(m.logger, stage, " ", name)
err = adapter.LegacyStart(endpoint, stage)
done()
if err != nil {
return E.Cause(err, stage, " ", name)
}
}
}
if existsEndpoint, loaded := m.endpointByTag[tag]; loaded {
if m.started {
err = existsEndpoint.Close()
if err != nil {
return E.Cause(err, "close endpoint/", existsEndpoint.Type(), "[", existsEndpoint.Tag(), "]")
}
}
existsIndex := common.Index(m.endpoints, func(it adapter.Endpoint) bool {
return it == existsEndpoint
})
if existsIndex == -1 {
panic("invalid endpoint index")
}
m.endpoints = append(m.endpoints[:existsIndex], m.endpoints[existsIndex+1:]...)
_, loaded := m.endpointByTag[tag]
if loaded {
return E.New("duplicate endpoint tag: ", tag)
}
m.endpoints = append(m.endpoints, endpoint)
m.endpointByTag[tag] = endpoint
-1
View File
@@ -40,7 +40,6 @@ type InboundManager interface {
Lifecycle
Inbounds() []Inbound
Get(tag string) (Inbound, bool)
Remove(tag string) error
Create(ctx context.Context, router Router, logger log.ContextLogger, tag string, inboundType string, options any) error
}
+4 -51
View File
@@ -2,14 +2,12 @@ package inbound
import (
"context"
"os"
"sync"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/taskmonitor"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
)
@@ -47,7 +45,7 @@ func (m *Manager) Start(stage adapter.StartStage) error {
for _, inbound := range inbounds {
name := "inbound/" + inbound.Type() + "[" + inbound.Tag() + "]"
done := adapter.LogElapsed(m.logger, stage, " ", name)
err := adapter.LegacyStart(inbound, stage)
err := inbound.Start(stage)
done()
if err != nil {
return E.Cause(err, stage, " ", name)
@@ -96,29 +94,6 @@ func (m *Manager) Get(tag string) (adapter.Inbound, bool) {
return m.endpoint.Get(tag)
}
func (m *Manager) Remove(tag string) error {
m.access.Lock()
inbound, found := m.inboundByTag[tag]
if !found {
m.access.Unlock()
return os.ErrInvalid
}
delete(m.inboundByTag, tag)
index := common.Index(m.inbounds, func(it adapter.Inbound) bool {
return it == inbound
})
if index == -1 {
panic("invalid inbound index")
}
m.inbounds = append(m.inbounds[:index], m.inbounds[index+1:]...)
started := m.started
m.access.Unlock()
if started {
return inbound.Close()
}
return nil
}
func (m *Manager) Create(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, outboundType string, options any) error {
inbound, err := m.registry.Create(ctx, router, logger, tag, outboundType, options)
if err != nil {
@@ -126,31 +101,9 @@ func (m *Manager) Create(ctx context.Context, router adapter.Router, logger log.
}
m.access.Lock()
defer m.access.Unlock()
if m.started {
name := "inbound/" + inbound.Type() + "[" + inbound.Tag() + "]"
for _, stage := range adapter.ListStartStages {
done := adapter.LogElapsed(m.logger, stage, " ", name)
err = adapter.LegacyStart(inbound, stage)
done()
if err != nil {
return E.Cause(err, stage, " ", name)
}
}
}
if existsInbound, loaded := m.inboundByTag[tag]; loaded {
if m.started {
err = existsInbound.Close()
if err != nil {
return E.Cause(err, "close inbound/", existsInbound.Type(), "[", existsInbound.Tag(), "]")
}
}
existsIndex := common.Index(m.inbounds, func(it adapter.Inbound) bool {
return it == existsInbound
})
if existsIndex == -1 {
panic("invalid inbound index")
}
m.inbounds = append(m.inbounds[:existsIndex], m.inbounds[existsIndex+1:]...)
_, loaded := m.inboundByTag[tag]
if loaded {
return E.New("duplicate inbound tag: ", tag)
}
m.inbounds = append(m.inbounds, inbound)
m.inboundByTag[tag] = inbound
-52
View File
@@ -1,52 +0,0 @@
package adapter
func LegacyStart(starter any, stage StartStage) error {
if lifecycle, isLifecycle := starter.(Lifecycle); isLifecycle {
return lifecycle.Start(stage)
}
switch stage {
case StartStateInitialize:
if preStarter, isPreStarter := starter.(interface {
PreStart() error
}); isPreStarter {
return preStarter.PreStart()
}
case StartStateStart:
if starter, isStarter := starter.(interface {
Start() error
}); isStarter {
return starter.Start()
}
case StartStateStarted:
if postStarter, isPostStarter := starter.(interface {
PostStart() error
}); isPostStarter {
return postStarter.PostStart()
}
}
return nil
}
type lifecycleServiceWrapper struct {
SimpleLifecycle
name string
}
func NewLifecycleService(service SimpleLifecycle, name string) LifecycleService {
return &lifecycleServiceWrapper{
SimpleLifecycle: service,
name: name,
}
}
func (l *lifecycleServiceWrapper) Name() string {
return l.name
}
func (l *lifecycleServiceWrapper) Start(stage StartStage) error {
return LegacyStart(l.SimpleLifecycle, stage)
}
func (l *lifecycleServiceWrapper) Close() error {
return l.SimpleLifecycle.Close()
}
-1
View File
@@ -47,7 +47,6 @@ type OutboundManager interface {
Outbounds() []Outbound
Outbound(tag string) (Outbound, bool)
Default() Outbound
Remove(tag string) error
Create(ctx context.Context, router Router, logger log.ContextLogger, tag string, outboundType string, options any) error
}
+8 -79
View File
@@ -28,7 +28,6 @@ type Manager struct {
stage adapter.StartStage
outbounds []adapter.Outbound
outboundByTag map[string]adapter.Outbound
dependByTag map[string][]string
defaultOutbound adapter.Outbound
defaultOutboundFallback func() (adapter.Outbound, error)
}
@@ -40,7 +39,6 @@ func NewManager(logger logger.ContextLogger, registry adapter.OutboundRegistry,
endpoint: endpoint,
defaultTag: defaultTag,
outboundByTag: make(map[string]adapter.Outbound),
dependByTag: make(map[string][]string),
}
}
@@ -81,9 +79,13 @@ func (m *Manager) Start(stage adapter.StartStage) error {
return m.startOutbounds(append(outbounds, common.Map(m.endpoint.Endpoints(), func(it adapter.Endpoint) adapter.Outbound { return it })...))
}
for _, outbound := range outbounds {
starter, isStarter := outbound.(adapter.Lifecycle)
if !isStarter {
continue
}
name := "outbound/" + outbound.Type() + "[" + outbound.Tag() + "]"
done := adapter.LogElapsed(m.logger, stage, " ", name)
err := adapter.LegacyStart(outbound, stage)
err := starter.Start(stage)
done()
if err != nil {
return E.Cause(err, stage, " ", name)
@@ -213,50 +215,6 @@ func (m *Manager) Default() adapter.Outbound {
return m.defaultOutbound
}
func (m *Manager) Remove(tag string) error {
m.access.Lock()
defer m.access.Unlock()
outbound, found := m.outboundByTag[tag]
if !found {
return os.ErrInvalid
}
delete(m.outboundByTag, tag)
index := common.Index(m.outbounds, func(it adapter.Outbound) bool {
return it == outbound
})
if index == -1 {
panic("invalid inbound index")
}
m.outbounds = append(m.outbounds[:index], m.outbounds[index+1:]...)
started := m.started
if m.defaultOutbound == outbound {
if len(m.outbounds) > 0 {
m.defaultOutbound = m.outbounds[0]
m.logger.Info("updated default outbound to ", m.defaultOutbound.Tag())
} else {
m.defaultOutbound = nil
}
}
dependBy := m.dependByTag[tag]
if len(dependBy) > 0 {
return E.New("outbound[", tag, "] is depended by ", strings.Join(dependBy, ", "))
}
dependencies := outbound.Dependencies()
for _, dependency := range dependencies {
if len(m.dependByTag[dependency]) == 1 {
delete(m.dependByTag, dependency)
} else {
m.dependByTag[dependency] = common.Filter(m.dependByTag[dependency], func(it string) bool {
return it != tag
})
}
}
if started {
return common.Close(outbound)
}
return nil
}
func (m *Manager) Create(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, inboundType string, options any) error {
if tag == "" {
return os.ErrInvalid
@@ -265,45 +223,16 @@ func (m *Manager) Create(ctx context.Context, router adapter.Router, logger log.
if err != nil {
return err
}
if m.started {
name := "outbound/" + outbound.Type() + "[" + outbound.Tag() + "]"
for _, stage := range adapter.ListStartStages {
done := adapter.LogElapsed(m.logger, stage, " ", name)
err = adapter.LegacyStart(outbound, stage)
done()
if err != nil {
return E.Cause(err, stage, " ", name)
}
}
}
m.access.Lock()
defer m.access.Unlock()
if existsOutbound, loaded := m.outboundByTag[tag]; loaded {
if m.started {
err = common.Close(existsOutbound)
if err != nil {
return E.Cause(err, "close outbound/", existsOutbound.Type(), "[", existsOutbound.Tag(), "]")
}
}
existsIndex := common.Index(m.outbounds, func(it adapter.Outbound) bool {
return it == existsOutbound
})
if existsIndex == -1 {
panic("invalid inbound index")
}
m.outbounds = append(m.outbounds[:existsIndex], m.outbounds[existsIndex+1:]...)
_, loaded := m.outboundByTag[tag]
if loaded {
return E.New("duplicate outbound tag: ", tag)
}
m.outbounds = append(m.outbounds, outbound)
m.outboundByTag[tag] = outbound
dependencies := outbound.Dependencies()
for _, dependency := range dependencies {
m.dependByTag[dependency] = append(m.dependByTag[dependency], tag)
}
if tag == m.defaultTag || (m.defaultTag == "" && m.defaultOutbound == nil) {
m.defaultOutbound = outbound
if m.started {
m.logger.Info("updated default outbound to ", outbound.Tag())
}
}
return nil
}
-1
View File
@@ -22,6 +22,5 @@ type ServiceManager interface {
Lifecycle
Services() []Service
Get(tag string) (Service, bool)
Remove(tag string) error
Create(ctx context.Context, logger log.ContextLogger, tag string, serviceType string, options any) error
}
+4 -51
View File
@@ -2,14 +2,12 @@ package service
import (
"context"
"os"
"sync"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/taskmonitor"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
)
@@ -45,7 +43,7 @@ func (m *Manager) Start(stage adapter.StartStage) error {
for _, service := range services {
name := "service/" + service.Type() + "[" + service.Tag() + "]"
done := adapter.LogElapsed(m.logger, stage, " ", name)
err := adapter.LegacyStart(service, stage)
err := service.Start(stage)
done()
if err != nil {
return E.Cause(err, stage, " ", name)
@@ -91,29 +89,6 @@ func (m *Manager) Get(tag string) (adapter.Service, bool) {
return service, found
}
func (m *Manager) Remove(tag string) error {
m.access.Lock()
service, found := m.serviceByTag[tag]
if !found {
m.access.Unlock()
return os.ErrInvalid
}
delete(m.serviceByTag, tag)
index := common.Index(m.services, func(it adapter.Service) bool {
return it == service
})
if index == -1 {
panic("invalid service index")
}
m.services = append(m.services[:index], m.services[index+1:]...)
started := m.started
m.access.Unlock()
if started {
return service.Close()
}
return nil
}
func (m *Manager) Create(ctx context.Context, logger log.ContextLogger, tag string, serviceType string, options any) error {
service, err := m.registry.Create(ctx, logger, tag, serviceType, options)
if err != nil {
@@ -121,31 +96,9 @@ func (m *Manager) Create(ctx context.Context, logger log.ContextLogger, tag stri
}
m.access.Lock()
defer m.access.Unlock()
if m.started {
name := "service/" + service.Type() + "[" + service.Tag() + "]"
for _, stage := range adapter.ListStartStages {
done := adapter.LogElapsed(m.logger, stage, " ", name)
err = adapter.LegacyStart(service, stage)
done()
if err != nil {
return E.Cause(err, stage, " ", name)
}
}
}
if existsService, loaded := m.serviceByTag[tag]; loaded {
if m.started {
err = existsService.Close()
if err != nil {
return E.Cause(err, "close service/", existsService.Type(), "[", existsService.Tag(), "]")
}
}
existsIndex := common.Index(m.services, func(it adapter.Service) bool {
return it == existsService
})
if existsIndex == -1 {
panic("invalid service index")
}
m.services = append(m.services[:existsIndex], m.services[existsIndex+1:]...)
_, loaded := m.serviceByTag[tag]
if loaded {
return E.New("duplicate service tag: ", tag)
}
m.services = append(m.services, service)
m.serviceByTag[tag] = service
+19 -2
View File
@@ -63,6 +63,7 @@ type Box struct {
referenceManager *route.ReferenceManager
httpClientService adapter.LifecycleService
internalService []adapter.LifecycleService
ntpService *ntp.Service
done chan struct{}
}
@@ -448,6 +449,7 @@ func New(options Options) (*Box, error) {
service.MustRegister[adapter.V2RayServer](ctx, v2rayServer)
}
}
var ntpService *ntp.Service
if ntpOptions.Enabled {
if ntpOptions.WriteToSystem {
err = adapter.CheckSecurityFeature(ctx, "NTP `write_to_system`")
@@ -459,7 +461,7 @@ func New(options Options) (*Box, error) {
if err != nil {
return nil, E.Cause(err, "create NTP service")
}
ntpService := ntp.NewService(ntp.Options{
ntpService = ntp.NewService(ntp.Options{
Context: ctx,
Dialer: ntpDialer,
Logger: logFactory.NewLogger("ntp"),
@@ -468,7 +470,6 @@ func New(options Options) (*Box, error) {
WriteToSystem: ntpOptions.WriteToSystem,
})
timeService.TimeService = ntpService
internalServices = append(internalServices, adapter.NewLifecycleService(ntpService, "ntp service"))
}
return &Box{
ctx: ctx,
@@ -489,6 +490,7 @@ func New(options Options) (*Box, error) {
logFactory: logFactory,
logger: logFactory.Logger(),
internalService: internalServices,
ntpService: ntpService,
done: make(chan struct{}),
}, nil
}
@@ -576,6 +578,14 @@ func (s *Box) start() error {
if err != nil {
return err
}
if s.ntpService != nil {
done := adapter.LogElapsed(s.logger, "start ntp service")
err = s.ntpService.Start()
done()
if err != nil {
return E.Cause(err, "start ntp service")
}
}
err = adapter.Start(s.ctx, s.logger, adapter.StartStateStart, s.endpoint)
if err != nil {
return err
@@ -657,6 +667,13 @@ func (s *Box) Close() error {
})
done()
}
if s.ntpService != nil {
done := adapter.LogElapsed(s.logger, "close ntp service")
err = E.Append(err, s.ntpService.Close(), func(err error) error {
return E.Cause(err, "close ntp service")
})
done()
}
done := adapter.LogElapsed(s.logger, "close logger")
err = E.Append(err, s.logFactory.Close(), func(err error) error {
return E.Cause(err, "close logger")
+1 -1
View File
@@ -62,7 +62,7 @@ type inlineCertificateProvider struct {
func (p *inlineCertificateProvider) Start() error {
for _, stage := range adapter.ListStartStages {
err := adapter.LegacyStart(p.provider, stage)
err := p.provider.Start(stage)
if err != nil {
return err
}
-4
View File
@@ -115,10 +115,6 @@ func (m *fakeDNSTransportManager) FakeIP() adapter.FakeIPTransport {
return nil
}
func (m *fakeDNSTransportManager) Remove(tag string) error {
return nil
}
func (m *fakeDNSTransportManager) Create(ctx context.Context, logger log.ContextLogger, tag string, outboundType string, options any) error {
return nil
}
+4 -80
View File
@@ -28,7 +28,6 @@ type TransportManager struct {
stage adapter.StartStage
transports []adapter.DNSTransport
transportByTag map[string]adapter.DNSTransport
dependByTag map[string][]string
defaultTransport adapter.DNSTransport
defaultTransportFallback func() (adapter.DNSTransport, error)
fakeIPTransport adapter.FakeIPTransport
@@ -41,7 +40,6 @@ func NewTransportManager(logger logger.ContextLogger, registry adapter.DNSTransp
outbound: outbound,
defaultTag: defaultTag,
transportByTag: make(map[string]adapter.DNSTransport),
dependByTag: make(map[string][]string),
}
}
@@ -78,7 +76,7 @@ func (m *TransportManager) Start(stage adapter.StartStage) error {
return m.startTransports(transports)
}
for _, transport := range transports {
err := adapter.LegacyStart(transport, stage)
err := transport.Start(stage)
if err != nil {
return E.Cause(err, stage, " dns/", transport.Type(), "[", transport.Tag(), "]")
}
@@ -193,54 +191,6 @@ func (m *TransportManager) FakeIP() adapter.FakeIPTransport {
return m.fakeIPTransport
}
func (m *TransportManager) Remove(tag string) error {
m.access.Lock()
defer m.access.Unlock()
transport, found := m.transportByTag[tag]
if !found {
return os.ErrInvalid
}
delete(m.transportByTag, tag)
index := common.Index(m.transports, func(it adapter.DNSTransport) bool {
return it == transport
})
if index == -1 {
panic("invalid inbound index")
}
m.transports = append(m.transports[:index], m.transports[index+1:]...)
started := m.started
if m.defaultTransport == transport {
if len(m.transports) > 0 {
nextTransport := m.transports[0]
if nextTransport.Type() != C.DNSTypeFakeIP {
return E.New("default server cannot be fakeip")
}
m.defaultTransport = nextTransport
m.logger.Info("updated default server to ", m.defaultTransport.Tag())
} else {
m.defaultTransport = nil
}
}
dependBy := m.dependByTag[tag]
if len(dependBy) > 0 {
return E.New("server[", tag, "] is depended by ", strings.Join(dependBy, ", "))
}
dependencies := transport.Dependencies()
for _, dependency := range dependencies {
if len(m.dependByTag[dependency]) == 1 {
delete(m.dependByTag, dependency)
} else {
m.dependByTag[dependency] = common.Filter(m.dependByTag[dependency], func(it string) bool {
return it != tag
})
}
}
if started {
transport.Close()
}
return nil
}
func (m *TransportManager) Create(ctx context.Context, logger log.ContextLogger, tag string, transportType string, options any) error {
if tag == "" {
return os.ErrInvalid
@@ -251,43 +201,17 @@ func (m *TransportManager) Create(ctx context.Context, logger log.ContextLogger,
}
m.access.Lock()
defer m.access.Unlock()
if m.started {
for _, stage := range adapter.ListStartStages {
err = adapter.LegacyStart(transport, stage)
if err != nil {
return E.Cause(err, stage, " dns/", transport.Type(), "[", transport.Tag(), "]")
}
}
}
if existsTransport, loaded := m.transportByTag[tag]; loaded {
if m.started {
err = common.Close(existsTransport)
if err != nil {
return E.Cause(err, "close dns/", existsTransport.Type(), "[", existsTransport.Tag(), "]")
}
}
existsIndex := common.Index(m.transports, func(it adapter.DNSTransport) bool {
return it == existsTransport
})
if existsIndex == -1 {
panic("invalid inbound index")
}
m.transports = append(m.transports[:existsIndex], m.transports[existsIndex+1:]...)
_, loaded := m.transportByTag[tag]
if loaded {
return E.New("duplicate DNS server tag: ", tag)
}
m.transports = append(m.transports, transport)
m.transportByTag[tag] = transport
dependencies := transport.Dependencies()
for _, dependency := range dependencies {
m.dependByTag[dependency] = append(m.dependByTag[dependency], tag)
}
if tag == m.defaultTag || (m.defaultTag == "" && m.defaultTransport == nil) {
if transport.Type() == C.DNSTypeFakeIP {
return E.New("default server cannot be fakeip")
}
m.defaultTransport = transport
if m.started {
m.logger.Info("updated default server to ", transport.Tag())
}
}
if transport.Type() == C.DNSTypeFakeIP {
if m.fakeIPTransport != nil {
+17 -17
View File
@@ -71,25 +71,25 @@ func NewURLTest(ctx context.Context, router adapter.Router, logger log.ContextLo
return outbound, nil
}
func (s *URLTest) Start() error {
outbounds := make([]adapter.Outbound, 0, len(s.tags))
for i, tag := range s.tags {
detour, loaded := s.outbound.Outbound(tag)
if !loaded {
return E.New("outbound ", i, " not found: ", tag)
func (s *URLTest) Start(stage adapter.StartStage) error {
switch stage {
case adapter.StartStateStart:
outbounds := make([]adapter.Outbound, 0, len(s.tags))
for i, tag := range s.tags {
detour, loaded := s.outbound.Outbound(tag)
if !loaded {
return E.New("outbound ", i, " not found: ", tag)
}
outbounds = append(outbounds, detour)
}
outbounds = append(outbounds, detour)
group, err := NewURLTestGroup(s.ctx, s.outbound, s.logger, outbounds, s.link, s.interval, s.tolerance, s.idleTimeout, s.interruptExternalConnections)
if err != nil {
return err
}
s.group = group
case adapter.StartStateStarted:
s.group.PostStart()
}
group, err := NewURLTestGroup(s.ctx, s.outbound, s.logger, outbounds, s.link, s.interval, s.tolerance, s.idleTimeout, s.interruptExternalConnections)
if err != nil {
return err
}
s.group = group
return nil
}
func (s *URLTest) PostStart() error {
s.group.PostStart()
return nil
}
-2
View File
@@ -61,8 +61,6 @@ func (s *countingRuleSet) Name() string { return s.name }
func (s *countingRuleSet) StartContext(context.Context, *adapter.HTTPStartContext) error { return nil }
func (s *countingRuleSet) PostStart() error { return nil }
func (s *countingRuleSet) Metadata() adapter.RuleSetMetadata { return adapter.RuleSetMetadata{} }
func (s *countingRuleSet) ExtractIPSet() []*netipx.IPSet { return nil }