service.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. package box
  2. import (
  3. "context"
  4. "net/netip"
  5. "github.com/sagernet/sing-box/adapter"
  6. "github.com/sagernet/sing-box/adapter/direct"
  7. "github.com/sagernet/sing-box/adapter/http"
  8. "github.com/sagernet/sing-box/adapter/mixed"
  9. "github.com/sagernet/sing-box/adapter/shadowsocks"
  10. "github.com/sagernet/sing-box/adapter/socks"
  11. "github.com/sagernet/sing-box/config"
  12. C "github.com/sagernet/sing-box/constant"
  13. "github.com/sagernet/sing-box/log"
  14. "github.com/sagernet/sing-box/route"
  15. "github.com/sagernet/sing/common"
  16. E "github.com/sagernet/sing/common/exceptions"
  17. F "github.com/sagernet/sing/common/format"
  18. "github.com/sirupsen/logrus"
  19. )
  20. var _ adapter.Service = (*Service)(nil)
  21. type Service struct {
  22. logger *logrus.Logger
  23. inbounds []adapter.Inbound
  24. outbounds []adapter.Outbound
  25. router *route.Router
  26. }
  27. func NewService(ctx context.Context, options *config.Config) (service *Service, err error) {
  28. logger := logrus.New()
  29. logger.SetLevel(logrus.TraceLevel)
  30. logger.Formatter.(*logrus.TextFormatter).ForceColors = true
  31. logger.AddHook(new(log.Hook))
  32. if options.Log != nil {
  33. if options.Log.Level != "" {
  34. logger.Level, err = logrus.ParseLevel(options.Log.Level)
  35. if err != nil {
  36. return
  37. }
  38. }
  39. }
  40. service = &Service{
  41. logger: logger,
  42. router: route.NewRouter(logrus.NewEntry(logger).WithFields(logrus.Fields{"prefix": "router: "})),
  43. }
  44. if len(options.Inbounds) > 0 {
  45. for i, inboundOptions := range options.Inbounds {
  46. var prefix string
  47. if inboundOptions.Tag != "" {
  48. prefix = inboundOptions.Tag
  49. } else {
  50. prefix = F.ToString(i)
  51. }
  52. prefix = F.ToString("inbound/", inboundOptions.Type, "[", prefix, "]: ")
  53. inboundLogger := logrus.NewEntry(logger).WithFields(logrus.Fields{"prefix": prefix})
  54. var inbound adapter.InboundHandler
  55. var listenOptions config.ListenOptions
  56. switch inboundOptions.Type {
  57. case C.TypeDirect:
  58. listenOptions = inboundOptions.DirectOptions.ListenOptions
  59. inbound = direct.NewInbound(service.router, inboundLogger, inboundOptions.DirectOptions)
  60. case C.TypeSocks:
  61. listenOptions = inboundOptions.SocksOptions.ListenOptions
  62. inbound = socks.NewInbound(service.router, inboundLogger, inboundOptions.SocksOptions)
  63. case C.TypeHTTP:
  64. listenOptions = inboundOptions.HTTPOptions.ListenOptions
  65. inbound = http.NewInbound(service.router, inboundLogger, inboundOptions.HTTPOptions)
  66. case C.TypeMixed:
  67. listenOptions = inboundOptions.MixedOptions.ListenOptions
  68. inbound = mixed.NewInbound(service.router, inboundLogger, inboundOptions.MixedOptions)
  69. case C.TypeShadowsocks:
  70. listenOptions = inboundOptions.ShadowsocksOptions.ListenOptions
  71. inbound, err = shadowsocks.NewInbound(service.router, inboundLogger, inboundOptions.ShadowsocksOptions)
  72. default:
  73. err = E.New("unknown inbound type: " + inboundOptions.Type)
  74. }
  75. if err != nil {
  76. return
  77. }
  78. service.inbounds = append(service.inbounds, adapter.NewDefaultInboundService(
  79. ctx,
  80. inboundOptions.Tag,
  81. inboundLogger,
  82. netip.AddrPortFrom(netip.Addr(listenOptions.Listen), listenOptions.Port),
  83. listenOptions.TCPFastOpen,
  84. inbound,
  85. ))
  86. }
  87. }
  88. for i, outboundOptions := range options.Outbounds {
  89. var prefix string
  90. if outboundOptions.Tag != "" {
  91. prefix = outboundOptions.Tag
  92. } else {
  93. prefix = F.ToString(i)
  94. }
  95. prefix = F.ToString("outbound/", outboundOptions.Type, "[", prefix, "]: ")
  96. outboundLogger := logrus.NewEntry(logger).WithFields(logrus.Fields{"prefix": prefix})
  97. var outbound adapter.Outbound
  98. switch outboundOptions.Type {
  99. case C.TypeDirect:
  100. outbound = direct.NewOutbound(outboundOptions.Tag, service.router, outboundLogger, outboundOptions.DirectOptions)
  101. case C.TypeShadowsocks:
  102. outbound, err = shadowsocks.NewOutbound(outboundOptions.Tag, service.router, outboundLogger, outboundOptions.ShadowsocksOptions)
  103. default:
  104. err = E.New("unknown outbound type: " + outboundOptions.Type)
  105. }
  106. if err != nil {
  107. return
  108. }
  109. service.outbounds = append(service.outbounds, outbound)
  110. service.router.AddOutbound(outbound)
  111. }
  112. if len(service.outbounds) == 0 {
  113. service.outbounds = append(service.outbounds, direct.NewOutbound("direct", service.router, logger, &config.DirectOutboundOptions{}))
  114. service.router.AddOutbound(service.outbounds[0])
  115. }
  116. return
  117. }
  118. func (s *Service) Start() error {
  119. for _, inbound := range s.inbounds {
  120. err := inbound.Start()
  121. if err != nil {
  122. return err
  123. }
  124. }
  125. return nil
  126. }
  127. func (s *Service) Close() error {
  128. for _, inbound := range s.inbounds {
  129. inbound.Close()
  130. }
  131. for _, outbound := range s.outbounds {
  132. common.Close(outbound)
  133. }
  134. return nil
  135. }