package core import ( "context" "sync" "v2ray.com/core/common" "v2ray.com/core/common/net" ) // InboundHandler is the interface for handlers that process inbound connections. type InboundHandler interface { common.Runnable // The tag of this handler. Tag() string // Deprecated. Do not use in new code. GetRandomInboundProxy() (interface{}, net.Port, int) } // OutboundHandler is the interface for handlers that process outbound connections. type OutboundHandler interface { common.Runnable Tag() string Dispatch(ctx context.Context, link *Link) } // InboundHandlerManager is a feature that manages InboundHandlers. type InboundHandlerManager interface { Feature // GetHandlers returns an InboundHandler for the given tag. GetHandler(ctx context.Context, tag string) (InboundHandler, error) // AddHandler adds the given handler into this InboundHandlerManager. AddHandler(ctx context.Context, handler InboundHandler) error // RemoveHandler removes a handler from InboundHandlerManager. RemoveHandler(ctx context.Context, tag string) error } type syncInboundHandlerManager struct { sync.RWMutex InboundHandlerManager } func (m *syncInboundHandlerManager) GetHandler(ctx context.Context, tag string) (InboundHandler, error) { m.RLock() defer m.RUnlock() if m.InboundHandlerManager == nil { return nil, newError("InboundHandlerManager not set.").AtError() } return m.InboundHandlerManager.GetHandler(ctx, tag) } func (m *syncInboundHandlerManager) AddHandler(ctx context.Context, handler InboundHandler) error { m.RLock() defer m.RUnlock() if m.InboundHandlerManager == nil { return newError("InboundHandlerManager not set.").AtError() } return m.InboundHandlerManager.AddHandler(ctx, handler) } func (m *syncInboundHandlerManager) Start() error { m.RLock() defer m.RUnlock() if m.InboundHandlerManager == nil { return newError("InboundHandlerManager not set.").AtError() } return m.InboundHandlerManager.Start() } func (m *syncInboundHandlerManager) Close() error { m.RLock() defer m.RUnlock() return common.Close(m.InboundHandlerManager) } func (m *syncInboundHandlerManager) Set(manager InboundHandlerManager) { if manager == nil { return } m.Lock() defer m.Unlock() common.Close(m.InboundHandlerManager) // nolint: errcheck m.InboundHandlerManager = manager } // OutboundHandlerManager is a feature that manages OutboundHandlers. type OutboundHandlerManager interface { Feature // GetHandler returns an OutboundHandler for the given tag. GetHandler(tag string) OutboundHandler // GetDefaultHandler returns the default OutboundHandler. It is usually the first OutboundHandler specified in the configuration. GetDefaultHandler() OutboundHandler // AddHandler adds a handler into this OutboundHandlerManager. AddHandler(ctx context.Context, handler OutboundHandler) error // RemoveHandler removes a handler from OutboundHandlerManager. RemoveHandler(ctx context.Context, tag string) error } type syncOutboundHandlerManager struct { sync.RWMutex OutboundHandlerManager } func (m *syncOutboundHandlerManager) GetHandler(tag string) OutboundHandler { m.RLock() defer m.RUnlock() if m.OutboundHandlerManager == nil { return nil } return m.OutboundHandlerManager.GetHandler(tag) } func (m *syncOutboundHandlerManager) GetDefaultHandler() OutboundHandler { m.RLock() defer m.RUnlock() if m.OutboundHandlerManager == nil { return nil } return m.OutboundHandlerManager.GetDefaultHandler() } func (m *syncOutboundHandlerManager) AddHandler(ctx context.Context, handler OutboundHandler) error { m.RLock() defer m.RUnlock() if m.OutboundHandlerManager == nil { return newError("OutboundHandlerManager not set.").AtError() } return m.OutboundHandlerManager.AddHandler(ctx, handler) } func (m *syncOutboundHandlerManager) Start() error { m.RLock() defer m.RUnlock() if m.OutboundHandlerManager == nil { return newError("OutboundHandlerManager not set.").AtError() } return m.OutboundHandlerManager.Start() } func (m *syncOutboundHandlerManager) Close() error { m.RLock() defer m.RUnlock() return common.Close(m.OutboundHandlerManager) } func (m *syncOutboundHandlerManager) Set(manager OutboundHandlerManager) { if manager == nil { return } m.Lock() defer m.Unlock() common.Close(m.OutboundHandlerManager) // nolint: errcheck m.OutboundHandlerManager = manager }