box.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601
  1. package box
  2. import (
  3. "context"
  4. "fmt"
  5. "io"
  6. "os"
  7. "runtime/debug"
  8. "time"
  9. "github.com/sagernet/sing-box/adapter"
  10. boxCertificate "github.com/sagernet/sing-box/adapter/certificate"
  11. "github.com/sagernet/sing-box/adapter/endpoint"
  12. "github.com/sagernet/sing-box/adapter/inbound"
  13. "github.com/sagernet/sing-box/adapter/outbound"
  14. boxService "github.com/sagernet/sing-box/adapter/service"
  15. "github.com/sagernet/sing-box/common/certificate"
  16. "github.com/sagernet/sing-box/common/dialer"
  17. "github.com/sagernet/sing-box/common/taskmonitor"
  18. "github.com/sagernet/sing-box/common/tls"
  19. C "github.com/sagernet/sing-box/constant"
  20. "github.com/sagernet/sing-box/dns"
  21. "github.com/sagernet/sing-box/dns/transport/local"
  22. "github.com/sagernet/sing-box/experimental"
  23. "github.com/sagernet/sing-box/experimental/cachefile"
  24. "github.com/sagernet/sing-box/log"
  25. "github.com/sagernet/sing-box/option"
  26. "github.com/sagernet/sing-box/protocol/direct"
  27. "github.com/sagernet/sing-box/route"
  28. "github.com/sagernet/sing/common"
  29. E "github.com/sagernet/sing/common/exceptions"
  30. F "github.com/sagernet/sing/common/format"
  31. "github.com/sagernet/sing/common/ntp"
  32. "github.com/sagernet/sing/service"
  33. "github.com/sagernet/sing/service/pause"
  34. )
  35. var _ adapter.SimpleLifecycle = (*Box)(nil)
  36. type Box struct {
  37. createdAt time.Time
  38. logFactory log.Factory
  39. logger log.ContextLogger
  40. network *route.NetworkManager
  41. endpoint *endpoint.Manager
  42. inbound *inbound.Manager
  43. outbound *outbound.Manager
  44. service *boxService.Manager
  45. certificateProvider *boxCertificate.Manager
  46. dnsTransport *dns.TransportManager
  47. dnsRouter *dns.Router
  48. connection *route.ConnectionManager
  49. router *route.Router
  50. internalService []adapter.LifecycleService
  51. done chan struct{}
  52. }
  53. type Options struct {
  54. option.Options
  55. Context context.Context
  56. PlatformLogWriter log.PlatformWriter
  57. }
  58. func Context(
  59. ctx context.Context,
  60. inboundRegistry adapter.InboundRegistry,
  61. outboundRegistry adapter.OutboundRegistry,
  62. endpointRegistry adapter.EndpointRegistry,
  63. dnsTransportRegistry adapter.DNSTransportRegistry,
  64. serviceRegistry adapter.ServiceRegistry,
  65. certificateProviderRegistry adapter.CertificateProviderRegistry,
  66. ) context.Context {
  67. if service.FromContext[option.InboundOptionsRegistry](ctx) == nil ||
  68. service.FromContext[adapter.InboundRegistry](ctx) == nil {
  69. ctx = service.ContextWith[option.InboundOptionsRegistry](ctx, inboundRegistry)
  70. ctx = service.ContextWith[adapter.InboundRegistry](ctx, inboundRegistry)
  71. }
  72. if service.FromContext[option.OutboundOptionsRegistry](ctx) == nil ||
  73. service.FromContext[adapter.OutboundRegistry](ctx) == nil {
  74. ctx = service.ContextWith[option.OutboundOptionsRegistry](ctx, outboundRegistry)
  75. ctx = service.ContextWith[adapter.OutboundRegistry](ctx, outboundRegistry)
  76. }
  77. if service.FromContext[option.EndpointOptionsRegistry](ctx) == nil ||
  78. service.FromContext[adapter.EndpointRegistry](ctx) == nil {
  79. ctx = service.ContextWith[option.EndpointOptionsRegistry](ctx, endpointRegistry)
  80. ctx = service.ContextWith[adapter.EndpointRegistry](ctx, endpointRegistry)
  81. }
  82. if service.FromContext[adapter.DNSTransportRegistry](ctx) == nil {
  83. ctx = service.ContextWith[option.DNSTransportOptionsRegistry](ctx, dnsTransportRegistry)
  84. ctx = service.ContextWith[adapter.DNSTransportRegistry](ctx, dnsTransportRegistry)
  85. }
  86. if service.FromContext[adapter.ServiceRegistry](ctx) == nil {
  87. ctx = service.ContextWith[option.ServiceOptionsRegistry](ctx, serviceRegistry)
  88. ctx = service.ContextWith[adapter.ServiceRegistry](ctx, serviceRegistry)
  89. }
  90. if service.FromContext[adapter.CertificateProviderRegistry](ctx) == nil {
  91. ctx = service.ContextWith[option.CertificateProviderOptionsRegistry](ctx, certificateProviderRegistry)
  92. ctx = service.ContextWith[adapter.CertificateProviderRegistry](ctx, certificateProviderRegistry)
  93. }
  94. return ctx
  95. }
  96. func New(options Options) (*Box, error) {
  97. createdAt := time.Now()
  98. ctx := options.Context
  99. if ctx == nil {
  100. ctx = context.Background()
  101. }
  102. ctx = service.ContextWithDefaultRegistry(ctx)
  103. endpointRegistry := service.FromContext[adapter.EndpointRegistry](ctx)
  104. inboundRegistry := service.FromContext[adapter.InboundRegistry](ctx)
  105. outboundRegistry := service.FromContext[adapter.OutboundRegistry](ctx)
  106. dnsTransportRegistry := service.FromContext[adapter.DNSTransportRegistry](ctx)
  107. serviceRegistry := service.FromContext[adapter.ServiceRegistry](ctx)
  108. certificateProviderRegistry := service.FromContext[adapter.CertificateProviderRegistry](ctx)
  109. if endpointRegistry == nil {
  110. return nil, E.New("missing endpoint registry in context")
  111. }
  112. if inboundRegistry == nil {
  113. return nil, E.New("missing inbound registry in context")
  114. }
  115. if outboundRegistry == nil {
  116. return nil, E.New("missing outbound registry in context")
  117. }
  118. if dnsTransportRegistry == nil {
  119. return nil, E.New("missing DNS transport registry in context")
  120. }
  121. if serviceRegistry == nil {
  122. return nil, E.New("missing service registry in context")
  123. }
  124. if certificateProviderRegistry == nil {
  125. return nil, E.New("missing certificate provider registry in context")
  126. }
  127. ctx = pause.WithDefaultManager(ctx)
  128. experimentalOptions := common.PtrValueOrDefault(options.Experimental)
  129. err := applyDebugOptions(common.PtrValueOrDefault(experimentalOptions.Debug))
  130. if err != nil {
  131. return nil, err
  132. }
  133. var needCacheFile bool
  134. var needClashAPI bool
  135. var needV2RayAPI bool
  136. if experimentalOptions.CacheFile != nil && experimentalOptions.CacheFile.Enabled || options.PlatformLogWriter != nil {
  137. needCacheFile = true
  138. }
  139. if experimentalOptions.ClashAPI != nil || options.PlatformLogWriter != nil {
  140. needClashAPI = true
  141. }
  142. if experimentalOptions.V2RayAPI != nil && experimentalOptions.V2RayAPI.Listen != "" {
  143. needV2RayAPI = true
  144. }
  145. platformInterface := service.FromContext[adapter.PlatformInterface](ctx)
  146. var defaultLogWriter io.Writer
  147. if platformInterface != nil {
  148. defaultLogWriter = io.Discard
  149. }
  150. logFactory, err := log.New(log.Options{
  151. Context: ctx,
  152. Options: common.PtrValueOrDefault(options.Log),
  153. Observable: needClashAPI,
  154. DefaultWriter: defaultLogWriter,
  155. BaseTime: createdAt,
  156. PlatformWriter: options.PlatformLogWriter,
  157. })
  158. if err != nil {
  159. return nil, E.Cause(err, "create log factory")
  160. }
  161. var internalServices []adapter.LifecycleService
  162. certificateOptions := common.PtrValueOrDefault(options.Certificate)
  163. if C.IsAndroid || certificateOptions.Store != "" && certificateOptions.Store != C.CertificateStoreSystem ||
  164. len(certificateOptions.Certificate) > 0 ||
  165. len(certificateOptions.CertificatePath) > 0 ||
  166. len(certificateOptions.CertificateDirectoryPath) > 0 {
  167. certificateStore, err := certificate.NewStore(ctx, logFactory.NewLogger("certificate"), certificateOptions)
  168. if err != nil {
  169. return nil, err
  170. }
  171. service.MustRegister[adapter.CertificateStore](ctx, certificateStore)
  172. internalServices = append(internalServices, certificateStore)
  173. }
  174. routeOptions := common.PtrValueOrDefault(options.Route)
  175. dnsOptions := common.PtrValueOrDefault(options.DNS)
  176. endpointManager := endpoint.NewManager(logFactory.NewLogger("endpoint"), endpointRegistry)
  177. inboundManager := inbound.NewManager(logFactory.NewLogger("inbound"), inboundRegistry, endpointManager)
  178. outboundManager := outbound.NewManager(logFactory.NewLogger("outbound"), outboundRegistry, endpointManager, routeOptions.Final)
  179. dnsTransportManager := dns.NewTransportManager(logFactory.NewLogger("dns/transport"), dnsTransportRegistry, outboundManager, dnsOptions.Final)
  180. serviceManager := boxService.NewManager(logFactory.NewLogger("service"), serviceRegistry)
  181. certificateProviderManager := boxCertificate.NewManager(logFactory.NewLogger("certificate-provider"), certificateProviderRegistry)
  182. service.MustRegister[adapter.EndpointManager](ctx, endpointManager)
  183. service.MustRegister[adapter.InboundManager](ctx, inboundManager)
  184. service.MustRegister[adapter.OutboundManager](ctx, outboundManager)
  185. service.MustRegister[adapter.DNSTransportManager](ctx, dnsTransportManager)
  186. service.MustRegister[adapter.ServiceManager](ctx, serviceManager)
  187. service.MustRegister[adapter.CertificateProviderManager](ctx, certificateProviderManager)
  188. dnsRouter := dns.NewRouter(ctx, logFactory, dnsOptions)
  189. service.MustRegister[adapter.DNSRouter](ctx, dnsRouter)
  190. networkManager, err := route.NewNetworkManager(ctx, logFactory.NewLogger("network"), routeOptions, dnsOptions)
  191. if err != nil {
  192. return nil, E.Cause(err, "initialize network manager")
  193. }
  194. service.MustRegister[adapter.NetworkManager](ctx, networkManager)
  195. connectionManager := route.NewConnectionManager(logFactory.NewLogger("connection"))
  196. service.MustRegister[adapter.ConnectionManager](ctx, connectionManager)
  197. router := route.NewRouter(ctx, logFactory, routeOptions, dnsOptions)
  198. service.MustRegister[adapter.Router](ctx, router)
  199. err = router.Initialize(routeOptions.Rules, routeOptions.RuleSet)
  200. if err != nil {
  201. return nil, E.Cause(err, "initialize router")
  202. }
  203. ntpOptions := common.PtrValueOrDefault(options.NTP)
  204. var timeService *tls.TimeServiceWrapper
  205. if ntpOptions.Enabled {
  206. timeService = new(tls.TimeServiceWrapper)
  207. service.MustRegister[ntp.TimeService](ctx, timeService)
  208. }
  209. for i, transportOptions := range dnsOptions.Servers {
  210. var tag string
  211. if transportOptions.Tag != "" {
  212. tag = transportOptions.Tag
  213. } else {
  214. tag = F.ToString(i)
  215. }
  216. err = dnsTransportManager.Create(
  217. ctx,
  218. logFactory.NewLogger(F.ToString("dns/", transportOptions.Type, "[", tag, "]")),
  219. tag,
  220. transportOptions.Type,
  221. transportOptions.Options,
  222. )
  223. if err != nil {
  224. return nil, E.Cause(err, "initialize DNS server[", i, "]")
  225. }
  226. }
  227. err = dnsRouter.Initialize(dnsOptions.Rules)
  228. if err != nil {
  229. return nil, E.Cause(err, "initialize dns router")
  230. }
  231. for i, endpointOptions := range options.Endpoints {
  232. var tag string
  233. if endpointOptions.Tag != "" {
  234. tag = endpointOptions.Tag
  235. } else {
  236. tag = F.ToString(i)
  237. }
  238. endpointCtx := ctx
  239. if tag != "" {
  240. // TODO: remove this
  241. endpointCtx = adapter.WithContext(endpointCtx, &adapter.InboundContext{
  242. Outbound: tag,
  243. })
  244. }
  245. err = endpointManager.Create(
  246. endpointCtx,
  247. router,
  248. logFactory.NewLogger(F.ToString("endpoint/", endpointOptions.Type, "[", tag, "]")),
  249. tag,
  250. endpointOptions.Type,
  251. endpointOptions.Options,
  252. )
  253. if err != nil {
  254. return nil, E.Cause(err, "initialize endpoint[", i, "]")
  255. }
  256. }
  257. for i, inboundOptions := range options.Inbounds {
  258. var tag string
  259. if inboundOptions.Tag != "" {
  260. tag = inboundOptions.Tag
  261. } else {
  262. tag = F.ToString(i)
  263. }
  264. err = inboundManager.Create(
  265. ctx,
  266. router,
  267. logFactory.NewLogger(F.ToString("inbound/", inboundOptions.Type, "[", tag, "]")),
  268. tag,
  269. inboundOptions.Type,
  270. inboundOptions.Options,
  271. )
  272. if err != nil {
  273. return nil, E.Cause(err, "initialize inbound[", i, "]")
  274. }
  275. }
  276. for i, serviceOptions := range options.Services {
  277. var tag string
  278. if serviceOptions.Tag != "" {
  279. tag = serviceOptions.Tag
  280. } else {
  281. tag = F.ToString(i)
  282. }
  283. err = serviceManager.Create(
  284. ctx,
  285. logFactory.NewLogger(F.ToString("service/", serviceOptions.Type, "[", tag, "]")),
  286. tag,
  287. serviceOptions.Type,
  288. serviceOptions.Options,
  289. )
  290. if err != nil {
  291. return nil, E.Cause(err, "initialize service[", i, "]")
  292. }
  293. }
  294. for i, outboundOptions := range options.Outbounds {
  295. var tag string
  296. if outboundOptions.Tag != "" {
  297. tag = outboundOptions.Tag
  298. } else {
  299. tag = F.ToString(i)
  300. }
  301. outboundCtx := ctx
  302. if tag != "" {
  303. // TODO: remove this
  304. outboundCtx = adapter.WithContext(outboundCtx, &adapter.InboundContext{
  305. Outbound: tag,
  306. })
  307. }
  308. err = outboundManager.Create(
  309. outboundCtx,
  310. router,
  311. logFactory.NewLogger(F.ToString("outbound/", outboundOptions.Type, "[", tag, "]")),
  312. tag,
  313. outboundOptions.Type,
  314. outboundOptions.Options,
  315. )
  316. if err != nil {
  317. return nil, E.Cause(err, "initialize outbound[", i, "]")
  318. }
  319. }
  320. for i, certificateProviderOptions := range options.CertificateProviders {
  321. var tag string
  322. if certificateProviderOptions.Tag != "" {
  323. tag = certificateProviderOptions.Tag
  324. } else {
  325. tag = F.ToString(i)
  326. }
  327. err = certificateProviderManager.Create(
  328. ctx,
  329. logFactory.NewLogger(F.ToString("certificate-provider/", certificateProviderOptions.Type, "[", tag, "]")),
  330. tag,
  331. certificateProviderOptions.Type,
  332. certificateProviderOptions.Options,
  333. )
  334. if err != nil {
  335. return nil, E.Cause(err, "initialize certificate provider[", i, "]")
  336. }
  337. }
  338. outboundManager.Initialize(func() (adapter.Outbound, error) {
  339. return direct.NewOutbound(
  340. ctx,
  341. router,
  342. logFactory.NewLogger("outbound/direct"),
  343. "direct",
  344. option.DirectOutboundOptions{},
  345. )
  346. })
  347. dnsTransportManager.Initialize(func() (adapter.DNSTransport, error) {
  348. return local.NewTransport(
  349. ctx,
  350. logFactory.NewLogger("dns/local"),
  351. "local",
  352. option.LocalDNSServerOptions{},
  353. )
  354. })
  355. if platformInterface != nil {
  356. err = platformInterface.Initialize(networkManager)
  357. if err != nil {
  358. return nil, E.Cause(err, "initialize platform interface")
  359. }
  360. }
  361. if needCacheFile {
  362. cacheFile := cachefile.New(ctx, common.PtrValueOrDefault(experimentalOptions.CacheFile))
  363. service.MustRegister[adapter.CacheFile](ctx, cacheFile)
  364. internalServices = append(internalServices, cacheFile)
  365. }
  366. if needClashAPI {
  367. clashAPIOptions := common.PtrValueOrDefault(experimentalOptions.ClashAPI)
  368. clashAPIOptions.ModeList = experimental.CalculateClashModeList(options.Options)
  369. clashServer, err := experimental.NewClashServer(ctx, logFactory.(log.ObservableFactory), clashAPIOptions)
  370. if err != nil {
  371. return nil, E.Cause(err, "create clash-server")
  372. }
  373. router.AppendTracker(clashServer)
  374. service.MustRegister[adapter.ClashServer](ctx, clashServer)
  375. internalServices = append(internalServices, clashServer)
  376. }
  377. if needV2RayAPI {
  378. v2rayServer, err := experimental.NewV2RayServer(logFactory.NewLogger("v2ray-api"), common.PtrValueOrDefault(experimentalOptions.V2RayAPI))
  379. if err != nil {
  380. return nil, E.Cause(err, "create v2ray-server")
  381. }
  382. if v2rayServer.StatsService() != nil {
  383. router.AppendTracker(v2rayServer.StatsService())
  384. internalServices = append(internalServices, v2rayServer)
  385. service.MustRegister[adapter.V2RayServer](ctx, v2rayServer)
  386. }
  387. }
  388. if ntpOptions.Enabled {
  389. ntpDialer, err := dialer.New(ctx, ntpOptions.DialerOptions, ntpOptions.ServerIsDomain())
  390. if err != nil {
  391. return nil, E.Cause(err, "create NTP service")
  392. }
  393. ntpService := ntp.NewService(ntp.Options{
  394. Context: ctx,
  395. Dialer: ntpDialer,
  396. Logger: logFactory.NewLogger("ntp"),
  397. Server: ntpOptions.ServerOptions.Build(),
  398. Interval: time.Duration(ntpOptions.Interval),
  399. WriteToSystem: ntpOptions.WriteToSystem,
  400. })
  401. timeService.TimeService = ntpService
  402. internalServices = append(internalServices, adapter.NewLifecycleService(ntpService, "ntp service"))
  403. }
  404. return &Box{
  405. network: networkManager,
  406. endpoint: endpointManager,
  407. inbound: inboundManager,
  408. outbound: outboundManager,
  409. dnsTransport: dnsTransportManager,
  410. service: serviceManager,
  411. certificateProvider: certificateProviderManager,
  412. dnsRouter: dnsRouter,
  413. connection: connectionManager,
  414. router: router,
  415. createdAt: createdAt,
  416. logFactory: logFactory,
  417. logger: logFactory.Logger(),
  418. internalService: internalServices,
  419. done: make(chan struct{}),
  420. }, nil
  421. }
  422. func (s *Box) PreStart() error {
  423. err := s.preStart()
  424. if err != nil {
  425. // TODO: remove catch error
  426. defer func() {
  427. v := recover()
  428. if v != nil {
  429. println(err.Error())
  430. debug.PrintStack()
  431. panic("panic on early close: " + fmt.Sprint(v))
  432. }
  433. }()
  434. s.Close()
  435. return err
  436. }
  437. s.logger.Info("sing-box pre-started (", F.Seconds(time.Since(s.createdAt).Seconds()), "s)")
  438. return nil
  439. }
  440. func (s *Box) Start() error {
  441. err := s.start()
  442. if err != nil {
  443. // TODO: remove catch error
  444. defer func() {
  445. v := recover()
  446. if v != nil {
  447. println(err.Error())
  448. debug.PrintStack()
  449. println("panic on early start: " + fmt.Sprint(v))
  450. }
  451. }()
  452. s.Close()
  453. return err
  454. }
  455. s.logger.Info("sing-box started (", F.Seconds(time.Since(s.createdAt).Seconds()), "s)")
  456. return nil
  457. }
  458. func (s *Box) preStart() error {
  459. monitor := taskmonitor.New(s.logger, C.StartTimeout)
  460. monitor.Start("start logger")
  461. err := s.logFactory.Start()
  462. monitor.Finish()
  463. if err != nil {
  464. return E.Cause(err, "start logger")
  465. }
  466. err = adapter.StartNamed(s.logger, adapter.StartStateInitialize, s.internalService) // cache-file clash-api v2ray-api
  467. if err != nil {
  468. return err
  469. }
  470. err = adapter.Start(s.logger, adapter.StartStateInitialize, s.network, s.dnsTransport, s.dnsRouter, s.connection, s.router, s.outbound, s.inbound, s.endpoint, s.service, s.certificateProvider)
  471. if err != nil {
  472. return err
  473. }
  474. err = adapter.Start(s.logger, adapter.StartStateStart, s.outbound, s.dnsTransport, s.dnsRouter, s.network, s.connection, s.router)
  475. if err != nil {
  476. return err
  477. }
  478. return nil
  479. }
  480. func (s *Box) start() error {
  481. err := s.preStart()
  482. if err != nil {
  483. return err
  484. }
  485. err = adapter.StartNamed(s.logger, adapter.StartStateStart, s.internalService)
  486. if err != nil {
  487. return err
  488. }
  489. err = adapter.Start(s.logger, adapter.StartStateStart, s.endpoint)
  490. if err != nil {
  491. return err
  492. }
  493. err = adapter.Start(s.logger, adapter.StartStateStart, s.certificateProvider)
  494. if err != nil {
  495. return err
  496. }
  497. err = adapter.Start(s.logger, adapter.StartStateStart, s.inbound, s.service)
  498. if err != nil {
  499. return err
  500. }
  501. err = adapter.Start(s.logger, adapter.StartStatePostStart, s.outbound, s.network, s.dnsTransport, s.dnsRouter, s.connection, s.router, s.endpoint, s.certificateProvider, s.inbound, s.service)
  502. if err != nil {
  503. return err
  504. }
  505. err = adapter.StartNamed(s.logger, adapter.StartStatePostStart, s.internalService)
  506. if err != nil {
  507. return err
  508. }
  509. err = adapter.Start(s.logger, adapter.StartStateStarted, s.network, s.dnsTransport, s.dnsRouter, s.connection, s.router, s.outbound, s.endpoint, s.certificateProvider, s.inbound, s.service)
  510. if err != nil {
  511. return err
  512. }
  513. err = adapter.StartNamed(s.logger, adapter.StartStateStarted, s.internalService)
  514. if err != nil {
  515. return err
  516. }
  517. return nil
  518. }
  519. func (s *Box) Close() error {
  520. select {
  521. case <-s.done:
  522. return os.ErrClosed
  523. default:
  524. close(s.done)
  525. }
  526. var err error
  527. for _, closeItem := range []struct {
  528. name string
  529. service adapter.Lifecycle
  530. }{
  531. {"service", s.service},
  532. {"inbound", s.inbound},
  533. {"certificate-provider", s.certificateProvider},
  534. {"endpoint", s.endpoint},
  535. {"outbound", s.outbound},
  536. {"router", s.router},
  537. {"connection", s.connection},
  538. {"dns-router", s.dnsRouter},
  539. {"dns-transport", s.dnsTransport},
  540. {"network", s.network},
  541. } {
  542. s.logger.Trace("close ", closeItem.name)
  543. startTime := time.Now()
  544. err = E.Append(err, closeItem.service.Close(), func(err error) error {
  545. return E.Cause(err, "close ", closeItem.name)
  546. })
  547. s.logger.Trace("close ", closeItem.name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)")
  548. }
  549. for _, lifecycleService := range s.internalService {
  550. s.logger.Trace("close ", lifecycleService.Name())
  551. startTime := time.Now()
  552. err = E.Append(err, lifecycleService.Close(), func(err error) error {
  553. return E.Cause(err, "close ", lifecycleService.Name())
  554. })
  555. s.logger.Trace("close ", lifecycleService.Name(), " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)")
  556. }
  557. s.logger.Trace("close logger")
  558. startTime := time.Now()
  559. err = E.Append(err, s.logFactory.Close(), func(err error) error {
  560. return E.Cause(err, "close logger")
  561. })
  562. s.logger.Trace("close logger completed (", F.Seconds(time.Since(startTime).Seconds()), "s)")
  563. return err
  564. }
  565. func (s *Box) Network() adapter.NetworkManager {
  566. return s.network
  567. }
  568. func (s *Box) Router() adapter.Router {
  569. return s.router
  570. }
  571. func (s *Box) Inbound() adapter.InboundManager {
  572. return s.inbound
  573. }
  574. func (s *Box) Outbound() adapter.OutboundManager {
  575. return s.outbound
  576. }
  577. func (s *Box) LogFactory() log.Factory {
  578. return s.logFactory
  579. }