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