github.com/EagleQL/Xray-core@v1.4.3/app/proxyman/inbound/inbound.go (about)

     1  package inbound
     2  
     3  //go:generate go run github.com/xtls/xray-core/common/errors/errorgen
     4  
     5  import (
     6  	"context"
     7  	"sync"
     8  
     9  	"github.com/xtls/xray-core/app/proxyman"
    10  	"github.com/xtls/xray-core/common"
    11  	"github.com/xtls/xray-core/common/serial"
    12  	"github.com/xtls/xray-core/common/session"
    13  	"github.com/xtls/xray-core/core"
    14  	"github.com/xtls/xray-core/features/inbound"
    15  )
    16  
    17  // Manager is to manage all inbound handlers.
    18  type Manager struct {
    19  	access          sync.RWMutex
    20  	untaggedHandler []inbound.Handler
    21  	taggedHandlers  map[string]inbound.Handler
    22  	running         bool
    23  }
    24  
    25  // New returns a new Manager for inbound handlers.
    26  func New(ctx context.Context, config *proxyman.InboundConfig) (*Manager, error) {
    27  	m := &Manager{
    28  		taggedHandlers: make(map[string]inbound.Handler),
    29  	}
    30  	return m, nil
    31  }
    32  
    33  // Type implements common.HasType.
    34  func (*Manager) Type() interface{} {
    35  	return inbound.ManagerType()
    36  }
    37  
    38  // AddHandler implements inbound.Manager.
    39  func (m *Manager) AddHandler(ctx context.Context, handler inbound.Handler) error {
    40  	m.access.Lock()
    41  	defer m.access.Unlock()
    42  
    43  	tag := handler.Tag()
    44  	if len(tag) > 0 {
    45  		if _, found := m.taggedHandlers[tag]; found {
    46  			return newError("existing tag found: " + tag)
    47  		}
    48  		m.taggedHandlers[tag] = handler
    49  	} else {
    50  		m.untaggedHandler = append(m.untaggedHandler, handler)
    51  	}
    52  
    53  	if m.running {
    54  		return handler.Start()
    55  	}
    56  
    57  	return nil
    58  }
    59  
    60  // GetHandler implements inbound.Manager.
    61  func (m *Manager) GetHandler(ctx context.Context, tag string) (inbound.Handler, error) {
    62  	m.access.RLock()
    63  	defer m.access.RUnlock()
    64  
    65  	handler, found := m.taggedHandlers[tag]
    66  	if !found {
    67  		return nil, newError("handler not found: ", tag)
    68  	}
    69  	return handler, nil
    70  }
    71  
    72  // RemoveHandler implements inbound.Manager.
    73  func (m *Manager) RemoveHandler(ctx context.Context, tag string) error {
    74  	if tag == "" {
    75  		return common.ErrNoClue
    76  	}
    77  
    78  	m.access.Lock()
    79  	defer m.access.Unlock()
    80  
    81  	if handler, found := m.taggedHandlers[tag]; found {
    82  		if err := handler.Close(); err != nil {
    83  			newError("failed to close handler ", tag).Base(err).AtWarning().WriteToLog(session.ExportIDToError(ctx))
    84  		}
    85  		delete(m.taggedHandlers, tag)
    86  		return nil
    87  	}
    88  
    89  	return common.ErrNoClue
    90  }
    91  
    92  // Start implements common.Runnable.
    93  func (m *Manager) Start() error {
    94  	m.access.Lock()
    95  	defer m.access.Unlock()
    96  
    97  	m.running = true
    98  
    99  	for _, handler := range m.taggedHandlers {
   100  		if err := handler.Start(); err != nil {
   101  			return err
   102  		}
   103  	}
   104  
   105  	for _, handler := range m.untaggedHandler {
   106  		if err := handler.Start(); err != nil {
   107  			return err
   108  		}
   109  	}
   110  	return nil
   111  }
   112  
   113  // Close implements common.Closable.
   114  func (m *Manager) Close() error {
   115  	m.access.Lock()
   116  	defer m.access.Unlock()
   117  
   118  	m.running = false
   119  
   120  	var errors []interface{}
   121  	for _, handler := range m.taggedHandlers {
   122  		if err := handler.Close(); err != nil {
   123  			errors = append(errors, err)
   124  		}
   125  	}
   126  	for _, handler := range m.untaggedHandler {
   127  		if err := handler.Close(); err != nil {
   128  			errors = append(errors, err)
   129  		}
   130  	}
   131  
   132  	if len(errors) > 0 {
   133  		return newError("failed to close all handlers").Base(newError(serial.Concat(errors...)))
   134  	}
   135  
   136  	return nil
   137  }
   138  
   139  // NewHandler creates a new inbound.Handler based on the given config.
   140  func NewHandler(ctx context.Context, config *core.InboundHandlerConfig) (inbound.Handler, error) {
   141  	rawReceiverSettings, err := config.ReceiverSettings.GetInstance()
   142  	if err != nil {
   143  		return nil, err
   144  	}
   145  	proxySettings, err := config.ProxySettings.GetInstance()
   146  	if err != nil {
   147  		return nil, err
   148  	}
   149  	tag := config.Tag
   150  
   151  	receiverSettings, ok := rawReceiverSettings.(*proxyman.ReceiverConfig)
   152  	if !ok {
   153  		return nil, newError("not a ReceiverConfig").AtError()
   154  	}
   155  
   156  	streamSettings := receiverSettings.StreamSettings
   157  	if streamSettings != nil && streamSettings.SocketSettings != nil {
   158  		ctx = session.ContextWithSockopt(ctx, &session.Sockopt{
   159  			Mark: streamSettings.SocketSettings.Mark,
   160  		})
   161  	}
   162  
   163  	allocStrategy := receiverSettings.AllocationStrategy
   164  	if allocStrategy == nil || allocStrategy.Type == proxyman.AllocationStrategy_Always {
   165  		return NewAlwaysOnInboundHandler(ctx, tag, receiverSettings, proxySettings)
   166  	}
   167  
   168  	if allocStrategy.Type == proxyman.AllocationStrategy_Random {
   169  		return NewDynamicInboundHandler(ctx, tag, receiverSettings, proxySettings)
   170  	}
   171  	return nil, newError("unknown allocation strategy: ", receiverSettings.AllocationStrategy.Type).AtError()
   172  }
   173  
   174  func init() {
   175  	common.Must(common.RegisterConfig((*proxyman.InboundConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
   176  		return New(ctx, config.(*proxyman.InboundConfig))
   177  	}))
   178  	common.Must(common.RegisterConfig((*core.InboundHandlerConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
   179  		return NewHandler(ctx, config.(*core.InboundHandlerConfig))
   180  	}))
   181  }