box.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. package box
  2. import (
  3. "context"
  4. "time"
  5. "github.com/sagernet/sing/common"
  6. E "github.com/sagernet/sing/common/exceptions"
  7. F "github.com/sagernet/sing/common/format"
  8. "github.com/sagernet/sing-box/adapter"
  9. "github.com/sagernet/sing-box/inbound"
  10. "github.com/sagernet/sing-box/log"
  11. "github.com/sagernet/sing-box/option"
  12. "github.com/sagernet/sing-box/outbound"
  13. "github.com/sagernet/sing-box/route"
  14. )
  15. var _ adapter.Service = (*Box)(nil)
  16. type Box struct {
  17. router adapter.Router
  18. logger log.Logger
  19. inbounds []adapter.Inbound
  20. outbounds []adapter.Outbound
  21. createdAt time.Time
  22. }
  23. func New(ctx context.Context, options option.Options) (*Box, error) {
  24. createdAt := time.Now()
  25. logger, err := log.NewLogger(common.PtrValueOrDefault(options.Log))
  26. if err != nil {
  27. return nil, E.Cause(err, "parse log options")
  28. }
  29. router, err := route.NewRouter(ctx, logger, common.PtrValueOrDefault(options.Route), common.PtrValueOrDefault(options.DNS))
  30. if err != nil {
  31. return nil, E.Cause(err, "parse route options")
  32. }
  33. inbounds := make([]adapter.Inbound, 0, len(options.Inbounds))
  34. outbounds := make([]adapter.Outbound, 0, len(options.Outbounds))
  35. for i, inboundOptions := range options.Inbounds {
  36. var in adapter.Inbound
  37. in, err = inbound.New(ctx, router, logger, i, inboundOptions)
  38. if err != nil {
  39. return nil, E.Cause(err, "parse inbound[", i, "]")
  40. }
  41. inbounds = append(inbounds, in)
  42. }
  43. for i, outboundOptions := range options.Outbounds {
  44. var out adapter.Outbound
  45. out, err = outbound.New(router, logger, i, outboundOptions)
  46. if err != nil {
  47. return nil, E.Cause(err, "parse outbound[", i, "]")
  48. }
  49. outbounds = append(outbounds, out)
  50. }
  51. err = router.Initialize(outbounds, func() adapter.Outbound {
  52. out, oErr := outbound.New(router, logger, 0, option.Outbound{Type: "direct", Tag: "default"})
  53. common.Must(oErr)
  54. outbounds = append(outbounds, out)
  55. return out
  56. })
  57. if err != nil {
  58. return nil, err
  59. }
  60. return &Box{
  61. router: router,
  62. logger: logger,
  63. inbounds: inbounds,
  64. outbounds: outbounds,
  65. createdAt: createdAt,
  66. }, nil
  67. }
  68. func (s *Box) Start() error {
  69. err := s.logger.Start()
  70. if err != nil {
  71. return err
  72. }
  73. err = s.router.Start()
  74. if err != nil {
  75. return err
  76. }
  77. for _, in := range s.inbounds {
  78. err = in.Start()
  79. if err != nil {
  80. return err
  81. }
  82. }
  83. s.logger.Info("sing-box started (", F.Seconds(time.Since(s.createdAt).Seconds()), "s)")
  84. return nil
  85. }
  86. func (s *Box) Close() error {
  87. for _, in := range s.inbounds {
  88. in.Close()
  89. }
  90. for _, out := range s.outbounds {
  91. common.Close(out)
  92. }
  93. return common.Close(
  94. s.router,
  95. s.logger,
  96. )
  97. }