diff --git a/adapter/certificate/manager.go b/adapter/certificate/manager.go index e4b9b535..55cd7c03 100644 --- a/adapter/certificate/manager.go +++ b/adapter/certificate/manager.go @@ -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 diff --git a/adapter/certificate_provider.go b/adapter/certificate_provider.go index 70bdeb88..b6b1e2f3 100644 --- a/adapter/certificate_provider.go +++ b/adapter/certificate_provider.go @@ -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 } diff --git a/adapter/dns.go b/adapter/dns.go index 15df285d..8119097e 100644 --- a/adapter/dns.go +++ b/adapter/dns.go @@ -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 } diff --git a/adapter/endpoint.go b/adapter/endpoint.go index f09f08ce..de416e23 100644 --- a/adapter/endpoint.go +++ b/adapter/endpoint.go @@ -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 } diff --git a/adapter/endpoint/manager.go b/adapter/endpoint/manager.go index 535c31b4..75487538 100644 --- a/adapter/endpoint/manager.go +++ b/adapter/endpoint/manager.go @@ -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 diff --git a/adapter/inbound.go b/adapter/inbound.go index 954ec9c4..b081ddc9 100644 --- a/adapter/inbound.go +++ b/adapter/inbound.go @@ -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 } diff --git a/adapter/inbound/manager.go b/adapter/inbound/manager.go index d6567cde..74c918d7 100644 --- a/adapter/inbound/manager.go +++ b/adapter/inbound/manager.go @@ -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 diff --git a/adapter/lifecycle_legacy.go b/adapter/lifecycle_legacy.go deleted file mode 100644 index f8b25db6..00000000 --- a/adapter/lifecycle_legacy.go +++ /dev/null @@ -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() -} diff --git a/adapter/outbound.go b/adapter/outbound.go index 73d93ddb..d8783cbe 100644 --- a/adapter/outbound.go +++ b/adapter/outbound.go @@ -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 } diff --git a/adapter/outbound/manager.go b/adapter/outbound/manager.go index 5314549d..5354bc9d 100644 --- a/adapter/outbound/manager.go +++ b/adapter/outbound/manager.go @@ -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 } diff --git a/adapter/service.go b/adapter/service.go index 534bd7eb..519b0abe 100644 --- a/adapter/service.go +++ b/adapter/service.go @@ -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 } diff --git a/adapter/service/manager.go b/adapter/service/manager.go index 1a83c503..22d6740a 100644 --- a/adapter/service/manager.go +++ b/adapter/service/manager.go @@ -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 diff --git a/box.go b/box.go index f1dbc3bf..ef3d497e 100644 --- a/box.go +++ b/box.go @@ -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") diff --git a/common/tls/std_server.go b/common/tls/std_server.go index ff4ee1a4..d611f72a 100644 --- a/common/tls/std_server.go +++ b/common/tls/std_server.go @@ -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 } diff --git a/dns/router_race_test.go b/dns/router_race_test.go index f0611ae0..910f9e91 100644 --- a/dns/router_race_test.go +++ b/dns/router_race_test.go @@ -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 } diff --git a/dns/transport_manager.go b/dns/transport_manager.go index 873cae82..120357c0 100644 --- a/dns/transport_manager.go +++ b/dns/transport_manager.go @@ -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 { diff --git a/protocol/group/urltest.go b/protocol/group/urltest.go index a264b2dd..01964896 100644 --- a/protocol/group/urltest.go +++ b/protocol/group/urltest.go @@ -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 } diff --git a/route/rule/rule_item_rule_set_test.go b/route/rule/rule_item_rule_set_test.go index a4e2e58c..61c3208b 100644 --- a/route/rule/rule_item_rule_set_test.go +++ b/route/rule/rule_item_rule_set_test.go @@ -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 }