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