outbound.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. package outbound
  2. //go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen
  3. import (
  4. "context"
  5. "strings"
  6. "sync"
  7. core "github.com/v2fly/v2ray-core/v5"
  8. "github.com/v2fly/v2ray-core/v5/app/proxyman"
  9. "github.com/v2fly/v2ray-core/v5/common"
  10. "github.com/v2fly/v2ray-core/v5/common/errors"
  11. "github.com/v2fly/v2ray-core/v5/common/session"
  12. "github.com/v2fly/v2ray-core/v5/features/outbound"
  13. )
  14. // Manager is to manage all outbound handlers.
  15. type Manager struct {
  16. access sync.RWMutex
  17. defaultHandler outbound.Handler
  18. taggedHandler map[string]outbound.Handler
  19. untaggedHandlers []outbound.Handler
  20. running bool
  21. }
  22. // New creates a new Manager.
  23. func New(ctx context.Context, config *proxyman.OutboundConfig) (*Manager, error) {
  24. m := &Manager{
  25. taggedHandler: make(map[string]outbound.Handler),
  26. }
  27. return m, nil
  28. }
  29. // Type implements common.HasType.
  30. func (m *Manager) Type() interface{} {
  31. return outbound.ManagerType()
  32. }
  33. // Start implements core.Feature
  34. func (m *Manager) Start() error {
  35. m.access.Lock()
  36. defer m.access.Unlock()
  37. m.running = true
  38. for _, h := range m.taggedHandler {
  39. if err := h.Start(); err != nil {
  40. return err
  41. }
  42. }
  43. for _, h := range m.untaggedHandlers {
  44. if err := h.Start(); err != nil {
  45. return err
  46. }
  47. }
  48. return nil
  49. }
  50. // Close implements core.Feature
  51. func (m *Manager) Close() error {
  52. m.access.Lock()
  53. defer m.access.Unlock()
  54. m.running = false
  55. var errs []error
  56. for _, h := range m.taggedHandler {
  57. errs = append(errs, h.Close())
  58. }
  59. for _, h := range m.untaggedHandlers {
  60. errs = append(errs, h.Close())
  61. }
  62. return errors.Combine(errs...)
  63. }
  64. // GetDefaultHandler implements outbound.Manager.
  65. func (m *Manager) GetDefaultHandler() outbound.Handler {
  66. m.access.RLock()
  67. defer m.access.RUnlock()
  68. return m.defaultHandler
  69. }
  70. // GetHandler implements outbound.Manager.
  71. func (m *Manager) GetHandler(tag string) outbound.Handler {
  72. m.access.RLock()
  73. defer m.access.RUnlock()
  74. if handler, found := m.taggedHandler[tag]; found {
  75. return handler
  76. }
  77. return nil
  78. }
  79. // AddHandler implements outbound.Manager.
  80. func (m *Manager) AddHandler(ctx context.Context, handler outbound.Handler) error {
  81. m.access.Lock()
  82. defer m.access.Unlock()
  83. tag := handler.Tag()
  84. if m.defaultHandler == nil ||
  85. (len(tag) > 0 && tag == m.defaultHandler.Tag()) {
  86. m.defaultHandler = handler
  87. }
  88. if len(tag) > 0 {
  89. if oldHandler, found := m.taggedHandler[tag]; found {
  90. errors.New("will replace the existed outbound with the tag: " + tag).AtWarning().WriteToLog()
  91. _ = oldHandler.Close()
  92. }
  93. m.taggedHandler[tag] = handler
  94. } else {
  95. m.untaggedHandlers = append(m.untaggedHandlers, handler)
  96. }
  97. if m.running {
  98. return handler.Start()
  99. }
  100. return nil
  101. }
  102. // RemoveHandler implements outbound.Manager.
  103. func (m *Manager) RemoveHandler(ctx context.Context, tag string) error {
  104. if tag == "" {
  105. return common.ErrNoClue
  106. }
  107. m.access.Lock()
  108. defer m.access.Unlock()
  109. if handler, found := m.taggedHandler[tag]; found {
  110. if err := handler.Close(); err != nil {
  111. newError("failed to close handler ", tag).Base(err).AtWarning().WriteToLog(session.ExportIDToError(ctx))
  112. }
  113. delete(m.taggedHandler, tag)
  114. if m.defaultHandler != nil && m.defaultHandler.Tag() == tag {
  115. m.defaultHandler = nil
  116. }
  117. return nil
  118. }
  119. return common.ErrNoClue
  120. }
  121. // Select implements outbound.HandlerSelector.
  122. func (m *Manager) Select(selectors []string) []string {
  123. m.access.RLock()
  124. defer m.access.RUnlock()
  125. tags := make([]string, 0, len(selectors))
  126. for tag := range m.taggedHandler {
  127. match := false
  128. for _, selector := range selectors {
  129. if strings.HasPrefix(tag, selector) {
  130. match = true
  131. break
  132. }
  133. }
  134. if match {
  135. tags = append(tags, tag)
  136. }
  137. }
  138. return tags
  139. }
  140. func init() {
  141. common.Must(common.RegisterConfig((*proxyman.OutboundConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
  142. return New(ctx, config.(*proxyman.OutboundConfig))
  143. }))
  144. common.Must(common.RegisterConfig((*core.OutboundHandlerConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
  145. return NewHandler(ctx, config.(*core.OutboundHandlerConfig))
  146. }))
  147. }