github.com/v2fly/v2ray-core/v5@v5.16.2-0.20240507031116-8191faa6e095/proxy/vmess/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 "io" 8 "strings" 9 "sync" 10 "time" 11 12 core "github.com/v2fly/v2ray-core/v5" 13 "github.com/v2fly/v2ray-core/v5/common" 14 "github.com/v2fly/v2ray-core/v5/common/buf" 15 "github.com/v2fly/v2ray-core/v5/common/errors" 16 "github.com/v2fly/v2ray-core/v5/common/log" 17 "github.com/v2fly/v2ray-core/v5/common/net" 18 "github.com/v2fly/v2ray-core/v5/common/platform" 19 "github.com/v2fly/v2ray-core/v5/common/protocol" 20 "github.com/v2fly/v2ray-core/v5/common/serial" 21 "github.com/v2fly/v2ray-core/v5/common/session" 22 "github.com/v2fly/v2ray-core/v5/common/signal" 23 "github.com/v2fly/v2ray-core/v5/common/task" 24 "github.com/v2fly/v2ray-core/v5/common/uuid" 25 feature_inbound "github.com/v2fly/v2ray-core/v5/features/inbound" 26 "github.com/v2fly/v2ray-core/v5/features/policy" 27 "github.com/v2fly/v2ray-core/v5/features/routing" 28 "github.com/v2fly/v2ray-core/v5/proxy/vmess" 29 "github.com/v2fly/v2ray-core/v5/proxy/vmess/encoding" 30 "github.com/v2fly/v2ray-core/v5/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, net.Network_UNIX} 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, err := session.EncodeResponseBody(request, output) 184 if err != nil { 185 return newError("failed to start decoding response").Base(err) 186 } 187 { 188 // Optimize for small response packet 189 data, err := input.ReadMultiBuffer() 190 if err != nil { 191 return err 192 } 193 194 if err := bodyWriter.WriteMultiBuffer(data); err != nil { 195 return err 196 } 197 } 198 199 if err := output.SetBuffered(false); err != nil { 200 return err 201 } 202 203 if err := buf.Copy(input, bodyWriter, buf.UpdateActivity(timer)); err != nil { 204 return err 205 } 206 207 account := request.User.Account.(*vmess.MemoryAccount) 208 209 if request.Option.Has(protocol.RequestOptionChunkStream) && !account.NoTerminationSignal { 210 if err := bodyWriter.WriteMultiBuffer(buf.MultiBuffer{}); err != nil { 211 return err 212 } 213 } 214 215 return nil 216 } 217 218 func isInsecureEncryption(s protocol.SecurityType) bool { 219 return s == protocol.SecurityType_NONE || s == protocol.SecurityType_LEGACY || s == protocol.SecurityType_UNKNOWN 220 } 221 222 // Process implements proxy.Inbound.Process(). 223 func (h *Handler) Process(ctx context.Context, network net.Network, connection internet.Connection, dispatcher routing.Dispatcher) error { 224 sessionPolicy := h.policyManager.ForLevel(0) 225 if err := connection.SetReadDeadline(time.Now().Add(sessionPolicy.Timeouts.Handshake)); err != nil { 226 return newError("unable to set read deadline").Base(err).AtWarning() 227 } 228 229 reader := &buf.BufferedReader{Reader: buf.NewReader(connection)} 230 svrSession := encoding.NewServerSession(h.clients, h.sessionHistory) 231 svrSession.SetAEADForced(aeadForced) 232 request, err := svrSession.DecodeRequestHeader(reader) 233 if err != nil { 234 if errors.Cause(err) != io.EOF { 235 log.Record(&log.AccessMessage{ 236 From: connection.RemoteAddr(), 237 To: "", 238 Status: log.AccessRejected, 239 Reason: err, 240 }) 241 err = newError("invalid request from ", connection.RemoteAddr()).Base(err).AtInfo() 242 } 243 return err 244 } 245 246 if h.secure && isInsecureEncryption(request.Security) { 247 log.Record(&log.AccessMessage{ 248 From: connection.RemoteAddr(), 249 To: "", 250 Status: log.AccessRejected, 251 Reason: "Insecure encryption", 252 Email: request.User.Email, 253 }) 254 return newError("client is using insecure encryption: ", request.Security) 255 } 256 257 if request.Command != protocol.RequestCommandMux { 258 ctx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{ 259 From: connection.RemoteAddr(), 260 To: request.Destination(), 261 Status: log.AccessAccepted, 262 Reason: "", 263 Email: request.User.Email, 264 }) 265 } 266 267 newError("received request for ", request.Destination()).WriteToLog(session.ExportIDToError(ctx)) 268 269 if err := connection.SetReadDeadline(time.Time{}); err != nil { 270 newError("unable to set back read deadline").Base(err).WriteToLog(session.ExportIDToError(ctx)) 271 } 272 273 inbound := session.InboundFromContext(ctx) 274 if inbound == nil { 275 panic("no inbound metadata") 276 } 277 inbound.User = request.User 278 279 sessionPolicy = h.policyManager.ForLevel(request.User.Level) 280 281 ctx, cancel := context.WithCancel(ctx) 282 timer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle) 283 284 ctx = policy.ContextWithBufferPolicy(ctx, sessionPolicy.Buffer) 285 link, err := dispatcher.Dispatch(ctx, request.Destination()) 286 if err != nil { 287 return newError("failed to dispatch request to ", request.Destination()).Base(err) 288 } 289 290 requestDone := func() error { 291 defer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly) 292 293 bodyReader, err := svrSession.DecodeRequestBody(request, reader) 294 if err != nil { 295 return newError("failed to start decoding").Base(err) 296 } 297 if err := buf.Copy(bodyReader, link.Writer, buf.UpdateActivity(timer)); err != nil { 298 return newError("failed to transfer request").Base(err) 299 } 300 return nil 301 } 302 303 responseDone := func() error { 304 defer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly) 305 306 writer := buf.NewBufferedWriter(buf.NewWriter(connection)) 307 defer writer.Flush() 308 309 response := &protocol.ResponseHeader{ 310 Command: h.generateCommand(ctx, request), 311 } 312 return transferResponse(timer, svrSession, request, response, link.Reader, writer) 313 } 314 315 requestDonePost := task.OnSuccess(requestDone, task.Close(link.Writer)) 316 if err := task.Run(ctx, requestDonePost, responseDone); err != nil { 317 common.Interrupt(link.Reader) 318 common.Interrupt(link.Writer) 319 return newError("connection ends").Base(err) 320 } 321 322 return nil 323 } 324 325 func (h *Handler) generateCommand(ctx context.Context, request *protocol.RequestHeader) protocol.ResponseCommand { 326 if h.detours != nil { 327 tag := h.detours.To 328 if h.inboundHandlerManager != nil { 329 handler, err := h.inboundHandlerManager.GetHandler(ctx, tag) 330 if err != nil { 331 newError("failed to get detour handler: ", tag).Base(err).AtWarning().WriteToLog(session.ExportIDToError(ctx)) 332 return nil 333 } 334 proxyHandler, port, availableMin := handler.GetRandomInboundProxy() 335 inboundHandler, ok := proxyHandler.(*Handler) 336 if ok && inboundHandler != nil { 337 if availableMin > 255 { 338 availableMin = 255 339 } 340 341 newError("pick detour handler for port ", port, " for ", availableMin, " minutes.").AtDebug().WriteToLog(session.ExportIDToError(ctx)) 342 user := inboundHandler.GetUser(request.User.Email) 343 if user == nil { 344 return nil 345 } 346 account := user.Account.(*vmess.MemoryAccount) 347 return &protocol.CommandSwitchAccount{ 348 Port: port, 349 ID: account.ID.UUID(), 350 AlterIds: uint16(len(account.AlterIDs)), 351 Level: user.Level, 352 ValidMin: byte(availableMin), 353 } 354 } 355 } 356 } 357 358 return nil 359 } 360 361 var ( 362 aeadForced = false 363 aeadForced2022 = false 364 ) 365 366 func init() { 367 common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) { 368 return New(ctx, config.(*Config)) 369 })) 370 371 common.Must(common.RegisterConfig((*SimplifiedConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) { 372 simplifiedServer := config.(*SimplifiedConfig) 373 fullConfig := &Config{ 374 User: func() (users []*protocol.User) { 375 for _, v := range simplifiedServer.Users { 376 account := &vmess.Account{Id: v} 377 users = append(users, &protocol.User{ 378 Account: serial.ToTypedMessage(account), 379 }) 380 } 381 return 382 }(), 383 } 384 385 return common.CreateObject(ctx, fullConfig) 386 })) 387 388 defaultFlagValue := "true_by_default_2022" 389 390 isAeadForced := platform.NewEnvFlag("v2ray.vmess.aead.forced").GetValue(func() string { return defaultFlagValue }) 391 if isAeadForced == "true" { 392 aeadForced = true 393 } 394 395 if isAeadForced == "true_by_default_2022" { 396 aeadForced = true 397 aeadForced2022 = true 398 } 399 }