github.com/Uhtred009/v2ray-core-1@v4.31.2+incompatible/proxy/vmess/inbound/inbound.go (about) 1 // +build !confonly 2 3 package inbound 4 5 //go:generate go run v2ray.com/core/common/errors/errorgen 6 7 import ( 8 "context" 9 "io" 10 "strings" 11 "sync" 12 "time" 13 14 "v2ray.com/core" 15 "v2ray.com/core/common" 16 "v2ray.com/core/common/buf" 17 "v2ray.com/core/common/errors" 18 "v2ray.com/core/common/log" 19 "v2ray.com/core/common/net" 20 "v2ray.com/core/common/protocol" 21 "v2ray.com/core/common/session" 22 "v2ray.com/core/common/signal" 23 "v2ray.com/core/common/task" 24 "v2ray.com/core/common/uuid" 25 feature_inbound "v2ray.com/core/features/inbound" 26 "v2ray.com/core/features/policy" 27 "v2ray.com/core/features/routing" 28 "v2ray.com/core/proxy/vmess" 29 "v2ray.com/core/proxy/vmess/encoding" 30 "v2ray.com/core/transport/internet" 31 ) 32 33 type userByEmail struct { 34 sync.Mutex 35 cache map[string]*protocol.MemoryUser 36 defaultLevel uint32 37 defaultAlterIDs uint16 38 } 39 40 func newUserByEmail(config *DefaultConfig) *userByEmail { 41 return &userByEmail{ 42 cache: make(map[string]*protocol.MemoryUser), 43 defaultLevel: config.Level, 44 defaultAlterIDs: uint16(config.AlterId), 45 } 46 } 47 48 func (v *userByEmail) addNoLock(u *protocol.MemoryUser) bool { 49 email := strings.ToLower(u.Email) 50 _, found := v.cache[email] 51 if found { 52 return false 53 } 54 v.cache[email] = u 55 return true 56 } 57 58 func (v *userByEmail) Add(u *protocol.MemoryUser) bool { 59 v.Lock() 60 defer v.Unlock() 61 62 return v.addNoLock(u) 63 } 64 65 func (v *userByEmail) Get(email string) (*protocol.MemoryUser, bool) { 66 email = strings.ToLower(email) 67 68 v.Lock() 69 defer v.Unlock() 70 71 user, found := v.cache[email] 72 if !found { 73 id := uuid.New() 74 rawAccount := &vmess.Account{ 75 Id: id.String(), 76 AlterId: uint32(v.defaultAlterIDs), 77 } 78 account, err := rawAccount.AsAccount() 79 common.Must(err) 80 user = &protocol.MemoryUser{ 81 Level: v.defaultLevel, 82 Email: email, 83 Account: account, 84 } 85 v.cache[email] = user 86 } 87 return user, found 88 } 89 90 func (v *userByEmail) Remove(email string) bool { 91 email = strings.ToLower(email) 92 93 v.Lock() 94 defer v.Unlock() 95 96 if _, found := v.cache[email]; !found { 97 return false 98 } 99 delete(v.cache, email) 100 return true 101 } 102 103 // Handler is an inbound connection handler that handles messages in VMess protocol. 104 type Handler struct { 105 policyManager policy.Manager 106 inboundHandlerManager feature_inbound.Manager 107 clients *vmess.TimedUserValidator 108 usersByEmail *userByEmail 109 detours *DetourConfig 110 sessionHistory *encoding.SessionHistory 111 secure bool 112 } 113 114 // New creates a new VMess inbound handler. 115 func New(ctx context.Context, config *Config) (*Handler, error) { 116 v := core.MustFromContext(ctx) 117 handler := &Handler{ 118 policyManager: v.GetFeature(policy.ManagerType()).(policy.Manager), 119 inboundHandlerManager: v.GetFeature(feature_inbound.ManagerType()).(feature_inbound.Manager), 120 clients: vmess.NewTimedUserValidator(protocol.DefaultIDHash), 121 detours: config.Detour, 122 usersByEmail: newUserByEmail(config.GetDefaultValue()), 123 sessionHistory: encoding.NewSessionHistory(), 124 secure: config.SecureEncryptionOnly, 125 } 126 127 for _, user := range config.User { 128 mUser, err := user.ToMemoryUser() 129 if err != nil { 130 return nil, newError("failed to get VMess user").Base(err) 131 } 132 133 if err := handler.AddUser(ctx, mUser); err != nil { 134 return nil, newError("failed to initiate user").Base(err) 135 } 136 } 137 138 return handler, nil 139 } 140 141 // Close implements common.Closable. 142 func (h *Handler) Close() error { 143 return errors.Combine( 144 h.clients.Close(), 145 h.sessionHistory.Close(), 146 common.Close(h.usersByEmail)) 147 } 148 149 // Network implements proxy.Inbound.Network(). 150 func (*Handler) Network() []net.Network { 151 return []net.Network{net.Network_TCP} 152 } 153 154 func (h *Handler) GetUser(email string) *protocol.MemoryUser { 155 user, existing := h.usersByEmail.Get(email) 156 if !existing { 157 h.clients.Add(user) 158 } 159 return user 160 } 161 162 func (h *Handler) AddUser(ctx context.Context, user *protocol.MemoryUser) error { 163 if len(user.Email) > 0 && !h.usersByEmail.Add(user) { 164 return newError("User ", user.Email, " already exists.") 165 } 166 return h.clients.Add(user) 167 } 168 169 func (h *Handler) RemoveUser(ctx context.Context, email string) error { 170 if email == "" { 171 return newError("Email must not be empty.") 172 } 173 if !h.usersByEmail.Remove(email) { 174 return newError("User ", email, " not found.") 175 } 176 h.clients.Remove(email) 177 return nil 178 } 179 180 func transferResponse(timer signal.ActivityUpdater, session *encoding.ServerSession, request *protocol.RequestHeader, response *protocol.ResponseHeader, input buf.Reader, output *buf.BufferedWriter) error { 181 session.EncodeResponseHeader(response, output) 182 183 bodyWriter := session.EncodeResponseBody(request, output) 184 185 { 186 // Optimize for small response packet 187 data, err := input.ReadMultiBuffer() 188 if err != nil { 189 return err 190 } 191 192 if err := bodyWriter.WriteMultiBuffer(data); err != nil { 193 return err 194 } 195 } 196 197 if err := output.SetBuffered(false); err != nil { 198 return err 199 } 200 201 if err := buf.Copy(input, bodyWriter, buf.UpdateActivity(timer)); err != nil { 202 return err 203 } 204 205 if request.Option.Has(protocol.RequestOptionChunkStream) { 206 if err := bodyWriter.WriteMultiBuffer(buf.MultiBuffer{}); err != nil { 207 return err 208 } 209 } 210 211 return nil 212 } 213 214 func isInsecureEncryption(s protocol.SecurityType) bool { 215 return s == protocol.SecurityType_NONE || s == protocol.SecurityType_LEGACY || s == protocol.SecurityType_UNKNOWN 216 } 217 218 // Process implements proxy.Inbound.Process(). 219 func (h *Handler) Process(ctx context.Context, network net.Network, connection internet.Connection, dispatcher routing.Dispatcher) error { 220 sessionPolicy := h.policyManager.ForLevel(0) 221 if err := connection.SetReadDeadline(time.Now().Add(sessionPolicy.Timeouts.Handshake)); err != nil { 222 return newError("unable to set read deadline").Base(err).AtWarning() 223 } 224 225 reader := &buf.BufferedReader{Reader: buf.NewReader(connection)} 226 svrSession := encoding.NewServerSession(h.clients, h.sessionHistory) 227 request, err := svrSession.DecodeRequestHeader(reader) 228 if err != nil { 229 if errors.Cause(err) != io.EOF { 230 log.Record(&log.AccessMessage{ 231 From: connection.RemoteAddr(), 232 To: "", 233 Status: log.AccessRejected, 234 Reason: err, 235 }) 236 err = newError("invalid request from ", connection.RemoteAddr()).Base(err).AtInfo() 237 } 238 return err 239 } 240 241 if h.secure && isInsecureEncryption(request.Security) { 242 log.Record(&log.AccessMessage{ 243 From: connection.RemoteAddr(), 244 To: "", 245 Status: log.AccessRejected, 246 Reason: "Insecure encryption", 247 Email: request.User.Email, 248 }) 249 return newError("client is using insecure encryption: ", request.Security) 250 } 251 252 if request.Command != protocol.RequestCommandMux { 253 ctx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{ 254 From: connection.RemoteAddr(), 255 To: request.Destination(), 256 Status: log.AccessAccepted, 257 Reason: "", 258 Email: request.User.Email, 259 }) 260 } 261 262 newError("received request for ", request.Destination()).WriteToLog(session.ExportIDToError(ctx)) 263 264 if err := connection.SetReadDeadline(time.Time{}); err != nil { 265 newError("unable to set back read deadline").Base(err).WriteToLog(session.ExportIDToError(ctx)) 266 } 267 268 inbound := session.InboundFromContext(ctx) 269 if inbound == nil { 270 panic("no inbound metadata") 271 } 272 inbound.User = request.User 273 274 sessionPolicy = h.policyManager.ForLevel(request.User.Level) 275 276 ctx, cancel := context.WithCancel(ctx) 277 timer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle) 278 279 ctx = policy.ContextWithBufferPolicy(ctx, sessionPolicy.Buffer) 280 link, err := dispatcher.Dispatch(ctx, request.Destination()) 281 if err != nil { 282 return newError("failed to dispatch request to ", request.Destination()).Base(err) 283 } 284 285 requestDone := func() error { 286 defer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly) 287 288 bodyReader := svrSession.DecodeRequestBody(request, reader) 289 if err := buf.Copy(bodyReader, link.Writer, buf.UpdateActivity(timer)); err != nil { 290 return newError("failed to transfer request").Base(err) 291 } 292 return nil 293 } 294 295 responseDone := func() error { 296 defer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly) 297 298 writer := buf.NewBufferedWriter(buf.NewWriter(connection)) 299 defer writer.Flush() 300 301 response := &protocol.ResponseHeader{ 302 Command: h.generateCommand(ctx, request), 303 } 304 return transferResponse(timer, svrSession, request, response, link.Reader, writer) 305 } 306 307 var requestDonePost = task.OnSuccess(requestDone, task.Close(link.Writer)) 308 if err := task.Run(ctx, requestDonePost, responseDone); err != nil { 309 common.Interrupt(link.Reader) 310 common.Interrupt(link.Writer) 311 return newError("connection ends").Base(err) 312 } 313 314 return nil 315 } 316 317 func (h *Handler) generateCommand(ctx context.Context, request *protocol.RequestHeader) protocol.ResponseCommand { 318 if h.detours != nil { 319 tag := h.detours.To 320 if h.inboundHandlerManager != nil { 321 handler, err := h.inboundHandlerManager.GetHandler(ctx, tag) 322 if err != nil { 323 newError("failed to get detour handler: ", tag).Base(err).AtWarning().WriteToLog(session.ExportIDToError(ctx)) 324 return nil 325 } 326 proxyHandler, port, availableMin := handler.GetRandomInboundProxy() 327 inboundHandler, ok := proxyHandler.(*Handler) 328 if ok && inboundHandler != nil { 329 if availableMin > 255 { 330 availableMin = 255 331 } 332 333 newError("pick detour handler for port ", port, " for ", availableMin, " minutes.").AtDebug().WriteToLog(session.ExportIDToError(ctx)) 334 user := inboundHandler.GetUser(request.User.Email) 335 if user == nil { 336 return nil 337 } 338 account := user.Account.(*vmess.MemoryAccount) 339 return &protocol.CommandSwitchAccount{ 340 Port: port, 341 ID: account.ID.UUID(), 342 AlterIds: uint16(len(account.AlterIDs)), 343 Level: user.Level, 344 ValidMin: byte(availableMin), 345 } 346 } 347 } 348 } 349 350 return nil 351 } 352 353 func init() { 354 common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) { 355 return New(ctx, config.(*Config)) 356 })) 357 }