github.com/xraypb/Xray-core@v1.8.1/proxy/vless/inbound/inbound.go (about) 1 package inbound 2 3 //go:generate go run github.com/xraypb/Xray-core/common/errors/errorgen 4 5 import ( 6 "bytes" 7 "context" 8 gotls "crypto/tls" 9 "io" 10 "reflect" 11 "strconv" 12 "strings" 13 "syscall" 14 "time" 15 "unsafe" 16 17 "github.com/pires/go-proxyproto" 18 "github.com/xraypb/Xray-core/common" 19 "github.com/xraypb/Xray-core/common/buf" 20 "github.com/xraypb/Xray-core/common/errors" 21 "github.com/xraypb/Xray-core/common/log" 22 "github.com/xraypb/Xray-core/common/net" 23 "github.com/xraypb/Xray-core/common/protocol" 24 "github.com/xraypb/Xray-core/common/retry" 25 "github.com/xraypb/Xray-core/common/session" 26 "github.com/xraypb/Xray-core/common/signal" 27 "github.com/xraypb/Xray-core/common/task" 28 "github.com/xraypb/Xray-core/core" 29 "github.com/xraypb/Xray-core/features/dns" 30 feature_inbound "github.com/xraypb/Xray-core/features/inbound" 31 "github.com/xraypb/Xray-core/features/policy" 32 "github.com/xraypb/Xray-core/features/routing" 33 "github.com/xraypb/Xray-core/features/stats" 34 "github.com/xraypb/Xray-core/proxy/vless" 35 "github.com/xraypb/Xray-core/proxy/vless/encoding" 36 "github.com/xraypb/Xray-core/transport/internet/reality" 37 "github.com/xraypb/Xray-core/transport/internet/stat" 38 "github.com/xraypb/Xray-core/transport/internet/tls" 39 ) 40 41 func init() { 42 common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) { 43 var dc dns.Client 44 if err := core.RequireFeatures(ctx, func(d dns.Client) error { 45 dc = d 46 return nil 47 }); err != nil { 48 return nil, err 49 } 50 return New(ctx, config.(*Config), dc) 51 })) 52 } 53 54 // Handler is an inbound connection handler that handles messages in VLess protocol. 55 type Handler struct { 56 inboundHandlerManager feature_inbound.Manager 57 policyManager policy.Manager 58 validator *vless.Validator 59 dns dns.Client 60 fallbacks map[string]map[string]map[string]*Fallback // or nil 61 // regexps map[string]*regexp.Regexp // or nil 62 } 63 64 // New creates a new VLess inbound handler. 65 func New(ctx context.Context, config *Config, dc dns.Client) (*Handler, error) { 66 v := core.MustFromContext(ctx) 67 handler := &Handler{ 68 inboundHandlerManager: v.GetFeature(feature_inbound.ManagerType()).(feature_inbound.Manager), 69 policyManager: v.GetFeature(policy.ManagerType()).(policy.Manager), 70 validator: new(vless.Validator), 71 dns: dc, 72 } 73 74 for _, user := range config.Clients { 75 u, err := user.ToMemoryUser() 76 if err != nil { 77 return nil, newError("failed to get VLESS user").Base(err).AtError() 78 } 79 if err := handler.AddUser(ctx, u); err != nil { 80 return nil, newError("failed to initiate user").Base(err).AtError() 81 } 82 } 83 84 if config.Fallbacks != nil { 85 handler.fallbacks = make(map[string]map[string]map[string]*Fallback) 86 // handler.regexps = make(map[string]*regexp.Regexp) 87 for _, fb := range config.Fallbacks { 88 if handler.fallbacks[fb.Name] == nil { 89 handler.fallbacks[fb.Name] = make(map[string]map[string]*Fallback) 90 } 91 if handler.fallbacks[fb.Name][fb.Alpn] == nil { 92 handler.fallbacks[fb.Name][fb.Alpn] = make(map[string]*Fallback) 93 } 94 handler.fallbacks[fb.Name][fb.Alpn][fb.Path] = fb 95 /* 96 if fb.Path != "" { 97 if r, err := regexp.Compile(fb.Path); err != nil { 98 return nil, newError("invalid path regexp").Base(err).AtError() 99 } else { 100 handler.regexps[fb.Path] = r 101 } 102 } 103 */ 104 } 105 if handler.fallbacks[""] != nil { 106 for name, apfb := range handler.fallbacks { 107 if name != "" { 108 for alpn := range handler.fallbacks[""] { 109 if apfb[alpn] == nil { 110 apfb[alpn] = make(map[string]*Fallback) 111 } 112 } 113 } 114 } 115 } 116 for _, apfb := range handler.fallbacks { 117 if apfb[""] != nil { 118 for alpn, pfb := range apfb { 119 if alpn != "" { // && alpn != "h2" { 120 for path, fb := range apfb[""] { 121 if pfb[path] == nil { 122 pfb[path] = fb 123 } 124 } 125 } 126 } 127 } 128 } 129 if handler.fallbacks[""] != nil { 130 for name, apfb := range handler.fallbacks { 131 if name != "" { 132 for alpn, pfb := range handler.fallbacks[""] { 133 for path, fb := range pfb { 134 if apfb[alpn][path] == nil { 135 apfb[alpn][path] = fb 136 } 137 } 138 } 139 } 140 } 141 } 142 } 143 144 return handler, nil 145 } 146 147 func isMuxAndNotXUDP(request *protocol.RequestHeader, first *buf.Buffer) bool { 148 if request.Command != protocol.RequestCommandMux { 149 return false 150 } 151 if first.Len() < 7 { 152 return true 153 } 154 firstBytes := first.Bytes() 155 return !(firstBytes[2] == 0 && // ID high 156 firstBytes[3] == 0 && // ID low 157 firstBytes[6] == 2) // Network type: UDP 158 } 159 160 // Close implements common.Closable.Close(). 161 func (h *Handler) Close() error { 162 return errors.Combine(common.Close(h.validator)) 163 } 164 165 // AddUser implements proxy.UserManager.AddUser(). 166 func (h *Handler) AddUser(ctx context.Context, u *protocol.MemoryUser) error { 167 return h.validator.Add(u) 168 } 169 170 // RemoveUser implements proxy.UserManager.RemoveUser(). 171 func (h *Handler) RemoveUser(ctx context.Context, e string) error { 172 return h.validator.Del(e) 173 } 174 175 // Network implements proxy.Inbound.Network(). 176 func (*Handler) Network() []net.Network { 177 return []net.Network{net.Network_TCP, net.Network_UNIX} 178 } 179 180 // Process implements proxy.Inbound.Process(). 181 func (h *Handler) Process(ctx context.Context, network net.Network, connection stat.Connection, dispatcher routing.Dispatcher) error { 182 sid := session.ExportIDToError(ctx) 183 184 iConn := connection 185 statConn, ok := iConn.(*stat.CounterConnection) 186 if ok { 187 iConn = statConn.Connection 188 } 189 190 sessionPolicy := h.policyManager.ForLevel(0) 191 if err := connection.SetReadDeadline(time.Now().Add(sessionPolicy.Timeouts.Handshake)); err != nil { 192 return newError("unable to set read deadline").Base(err).AtWarning() 193 } 194 195 first := buf.FromBytes(make([]byte, buf.Size)) 196 first.Clear() 197 firstLen, _ := first.ReadFrom(connection) 198 newError("firstLen = ", firstLen).AtInfo().WriteToLog(sid) 199 200 reader := &buf.BufferedReader{ 201 Reader: buf.NewReader(connection), 202 Buffer: buf.MultiBuffer{first}, 203 } 204 205 var request *protocol.RequestHeader 206 var requestAddons *encoding.Addons 207 var err error 208 209 napfb := h.fallbacks 210 isfb := napfb != nil 211 212 if isfb && firstLen < 18 { 213 err = newError("fallback directly") 214 } else { 215 request, requestAddons, isfb, err = encoding.DecodeRequestHeader(isfb, first, reader, h.validator) 216 } 217 218 if err != nil { 219 if isfb { 220 if err := connection.SetReadDeadline(time.Time{}); err != nil { 221 newError("unable to set back read deadline").Base(err).AtWarning().WriteToLog(sid) 222 } 223 newError("fallback starts").Base(err).AtInfo().WriteToLog(sid) 224 225 name := "" 226 alpn := "" 227 if tlsConn, ok := iConn.(*tls.Conn); ok { 228 cs := tlsConn.ConnectionState() 229 name = cs.ServerName 230 alpn = cs.NegotiatedProtocol 231 newError("realName = " + name).AtInfo().WriteToLog(sid) 232 newError("realAlpn = " + alpn).AtInfo().WriteToLog(sid) 233 } else if realityConn, ok := iConn.(*reality.Conn); ok { 234 cs := realityConn.ConnectionState() 235 name = cs.ServerName 236 alpn = cs.NegotiatedProtocol 237 newError("realName = " + name).AtInfo().WriteToLog(sid) 238 newError("realAlpn = " + alpn).AtInfo().WriteToLog(sid) 239 } 240 name = strings.ToLower(name) 241 alpn = strings.ToLower(alpn) 242 243 if len(napfb) > 1 || napfb[""] == nil { 244 if name != "" && napfb[name] == nil { 245 match := "" 246 for n := range napfb { 247 if n != "" && strings.Contains(name, n) && len(n) > len(match) { 248 match = n 249 } 250 } 251 name = match 252 } 253 } 254 255 if napfb[name] == nil { 256 name = "" 257 } 258 apfb := napfb[name] 259 if apfb == nil { 260 return newError(`failed to find the default "name" config`).AtWarning() 261 } 262 263 if apfb[alpn] == nil { 264 alpn = "" 265 } 266 pfb := apfb[alpn] 267 if pfb == nil { 268 return newError(`failed to find the default "alpn" config`).AtWarning() 269 } 270 271 path := "" 272 if len(pfb) > 1 || pfb[""] == nil { 273 /* 274 if lines := bytes.Split(firstBytes, []byte{'\r', '\n'}); len(lines) > 1 { 275 if s := bytes.Split(lines[0], []byte{' '}); len(s) == 3 { 276 if len(s[0]) < 8 && len(s[1]) > 0 && len(s[2]) == 8 { 277 newError("realPath = " + string(s[1])).AtInfo().WriteToLog(sid) 278 for _, fb := range pfb { 279 if fb.Path != "" && h.regexps[fb.Path].Match(s[1]) { 280 path = fb.Path 281 break 282 } 283 } 284 } 285 } 286 } 287 */ 288 if firstLen >= 18 && first.Byte(4) != '*' { // not h2c 289 firstBytes := first.Bytes() 290 for i := 4; i <= 8; i++ { // 5 -> 9 291 if firstBytes[i] == '/' && firstBytes[i-1] == ' ' { 292 search := len(firstBytes) 293 if search > 64 { 294 search = 64 // up to about 60 295 } 296 for j := i + 1; j < search; j++ { 297 k := firstBytes[j] 298 if k == '\r' || k == '\n' { // avoid logging \r or \n 299 break 300 } 301 if k == '?' || k == ' ' { 302 path = string(firstBytes[i:j]) 303 newError("realPath = " + path).AtInfo().WriteToLog(sid) 304 if pfb[path] == nil { 305 path = "" 306 } 307 break 308 } 309 } 310 break 311 } 312 } 313 } 314 } 315 fb := pfb[path] 316 if fb == nil { 317 return newError(`failed to find the default "path" config`).AtWarning() 318 } 319 320 ctx, cancel := context.WithCancel(ctx) 321 timer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle) 322 ctx = policy.ContextWithBufferPolicy(ctx, sessionPolicy.Buffer) 323 324 var conn net.Conn 325 if err := retry.ExponentialBackoff(5, 100).On(func() error { 326 var dialer net.Dialer 327 conn, err = dialer.DialContext(ctx, fb.Type, fb.Dest) 328 if err != nil { 329 return err 330 } 331 return nil 332 }); err != nil { 333 return newError("failed to dial to " + fb.Dest).Base(err).AtWarning() 334 } 335 defer conn.Close() 336 337 serverReader := buf.NewReader(conn) 338 serverWriter := buf.NewWriter(conn) 339 340 postRequest := func() error { 341 defer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly) 342 if fb.Xver != 0 { 343 ipType := 4 344 remoteAddr, remotePort, err := net.SplitHostPort(connection.RemoteAddr().String()) 345 if err != nil { 346 ipType = 0 347 } 348 localAddr, localPort, err := net.SplitHostPort(connection.LocalAddr().String()) 349 if err != nil { 350 ipType = 0 351 } 352 if ipType == 4 { 353 for i := 0; i < len(remoteAddr); i++ { 354 if remoteAddr[i] == ':' { 355 ipType = 6 356 break 357 } 358 } 359 } 360 pro := buf.New() 361 defer pro.Release() 362 switch fb.Xver { 363 case 1: 364 if ipType == 0 { 365 pro.Write([]byte("PROXY UNKNOWN\r\n")) 366 break 367 } 368 if ipType == 4 { 369 pro.Write([]byte("PROXY TCP4 " + remoteAddr + " " + localAddr + " " + remotePort + " " + localPort + "\r\n")) 370 } else { 371 pro.Write([]byte("PROXY TCP6 " + remoteAddr + " " + localAddr + " " + remotePort + " " + localPort + "\r\n")) 372 } 373 case 2: 374 pro.Write([]byte("\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A")) // signature 375 if ipType == 0 { 376 pro.Write([]byte("\x20\x00\x00\x00")) // v2 + LOCAL + UNSPEC + UNSPEC + 0 bytes 377 break 378 } 379 if ipType == 4 { 380 pro.Write([]byte("\x21\x11\x00\x0C")) // v2 + PROXY + AF_INET + STREAM + 12 bytes 381 pro.Write(net.ParseIP(remoteAddr).To4()) 382 pro.Write(net.ParseIP(localAddr).To4()) 383 } else { 384 pro.Write([]byte("\x21\x21\x00\x24")) // v2 + PROXY + AF_INET6 + STREAM + 36 bytes 385 pro.Write(net.ParseIP(remoteAddr).To16()) 386 pro.Write(net.ParseIP(localAddr).To16()) 387 } 388 p1, _ := strconv.ParseUint(remotePort, 10, 16) 389 p2, _ := strconv.ParseUint(localPort, 10, 16) 390 pro.Write([]byte{byte(p1 >> 8), byte(p1), byte(p2 >> 8), byte(p2)}) 391 } 392 if err := serverWriter.WriteMultiBuffer(buf.MultiBuffer{pro}); err != nil { 393 return newError("failed to set PROXY protocol v", fb.Xver).Base(err).AtWarning() 394 } 395 } 396 if err := buf.Copy(reader, serverWriter, buf.UpdateActivity(timer)); err != nil { 397 return newError("failed to fallback request payload").Base(err).AtInfo() 398 } 399 return nil 400 } 401 402 writer := buf.NewWriter(connection) 403 404 getResponse := func() error { 405 defer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly) 406 if err := buf.Copy(serverReader, writer, buf.UpdateActivity(timer)); err != nil { 407 return newError("failed to deliver response payload").Base(err).AtInfo() 408 } 409 return nil 410 } 411 412 if err := task.Run(ctx, task.OnSuccess(postRequest, task.Close(serverWriter)), task.OnSuccess(getResponse, task.Close(writer))); err != nil { 413 common.Interrupt(serverReader) 414 common.Interrupt(serverWriter) 415 return newError("fallback ends").Base(err).AtInfo() 416 } 417 return nil 418 } 419 420 if errors.Cause(err) != io.EOF { 421 log.Record(&log.AccessMessage{ 422 From: connection.RemoteAddr(), 423 To: "", 424 Status: log.AccessRejected, 425 Reason: err, 426 }) 427 err = newError("invalid request from ", connection.RemoteAddr()).Base(err).AtInfo() 428 } 429 return err 430 } 431 432 if err := connection.SetReadDeadline(time.Time{}); err != nil { 433 newError("unable to set back read deadline").Base(err).AtWarning().WriteToLog(sid) 434 } 435 newError("received request for ", request.Destination()).AtInfo().WriteToLog(sid) 436 437 inbound := session.InboundFromContext(ctx) 438 if inbound == nil { 439 panic("no inbound metadata") 440 } 441 inbound.Name = "vless" 442 inbound.User = request.User 443 444 account := request.User.Account.(*vless.MemoryAccount) 445 446 responseAddons := &encoding.Addons{ 447 // Flow: requestAddons.Flow, 448 } 449 450 var netConn net.Conn 451 var rawConn syscall.RawConn 452 var input *bytes.Reader 453 var rawInput *bytes.Buffer 454 455 switch requestAddons.Flow { 456 case vless.XRV: 457 if account.Flow == requestAddons.Flow { 458 switch request.Command { 459 case protocol.RequestCommandMux: 460 return newError(requestAddons.Flow + " doesn't support Mux").AtWarning() 461 case protocol.RequestCommandUDP: 462 return newError(requestAddons.Flow + " doesn't support UDP").AtWarning() 463 case protocol.RequestCommandTCP: 464 var t reflect.Type 465 var p uintptr 466 if tlsConn, ok := iConn.(*tls.Conn); ok { 467 if tlsConn.ConnectionState().Version != gotls.VersionTLS13 { 468 return newError(`failed to use `+requestAddons.Flow+`, found outer tls version `, tlsConn.ConnectionState().Version).AtWarning() 469 } 470 netConn = tlsConn.NetConn() 471 t = reflect.TypeOf(tlsConn.Conn).Elem() 472 p = uintptr(unsafe.Pointer(tlsConn.Conn)) 473 } else if realityConn, ok := iConn.(*reality.Conn); ok { 474 netConn = realityConn.NetConn() 475 t = reflect.TypeOf(realityConn.Conn).Elem() 476 p = uintptr(unsafe.Pointer(realityConn.Conn)) 477 } else if _, ok := iConn.(*tls.UConn); ok { 478 return newError("XTLS only supports UTLS fingerprint for the outbound.").AtWarning() 479 } else { 480 return newError("XTLS only supports TCP, mKCP and DomainSocket for now.").AtWarning() 481 } 482 if pc, ok := netConn.(*proxyproto.Conn); ok { 483 netConn = pc.Raw() 484 // 8192 > 4096, there is no need to process pc's bufReader 485 } 486 if sc, ok := netConn.(syscall.Conn); ok { 487 rawConn, _ = sc.SyscallConn() 488 } 489 i, _ := t.FieldByName("input") 490 r, _ := t.FieldByName("rawInput") 491 input = (*bytes.Reader)(unsafe.Pointer(p + i.Offset)) 492 rawInput = (*bytes.Buffer)(unsafe.Pointer(p + r.Offset)) 493 } 494 } else { 495 return newError(account.ID.String() + " is not able to use " + requestAddons.Flow).AtWarning() 496 } 497 case "": 498 if account.Flow == vless.XRV && (request.Command == protocol.RequestCommandTCP || isMuxAndNotXUDP(request, first)) { 499 return newError(account.ID.String() + " is not able to use \"\". Note that the pure TLS proxy has certain TLS in TLS characters.").AtWarning() 500 } 501 default: 502 return newError("unknown request flow " + requestAddons.Flow).AtWarning() 503 } 504 505 if request.Command != protocol.RequestCommandMux { 506 ctx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{ 507 From: connection.RemoteAddr(), 508 To: request.Destination(), 509 Status: log.AccessAccepted, 510 Reason: "", 511 Email: request.User.Email, 512 }) 513 } 514 515 sessionPolicy = h.policyManager.ForLevel(request.User.Level) 516 ctx, cancel := context.WithCancel(ctx) 517 timer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle) 518 ctx = policy.ContextWithBufferPolicy(ctx, sessionPolicy.Buffer) 519 520 link, err := dispatcher.Dispatch(ctx, request.Destination()) 521 if err != nil { 522 return newError("failed to dispatch request to ", request.Destination()).Base(err).AtWarning() 523 } 524 525 serverReader := link.Reader // .(*pipe.Reader) 526 serverWriter := link.Writer // .(*pipe.Writer) 527 enableXtls := false 528 isTLS12orAbove := false 529 isTLS := false 530 var cipher uint16 = 0 531 var remainingServerHello int32 = -1 532 numberOfPacketToFilter := 8 533 534 postRequest := func() error { 535 defer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly) 536 537 // default: clientReader := reader 538 clientReader := encoding.DecodeBodyAddons(reader, request, requestAddons) 539 540 var err error 541 542 if rawConn != nil { 543 var counter stats.Counter 544 if statConn != nil { 545 counter = statConn.ReadCounter 546 } 547 // TODO enable splice 548 ctx = session.ContextWithInbound(ctx, nil) 549 err = encoding.XtlsRead(clientReader, serverWriter, timer, netConn, rawConn, input, rawInput, counter, ctx, account.ID.Bytes(), 550 &numberOfPacketToFilter, &enableXtls, &isTLS12orAbove, &isTLS, &cipher, &remainingServerHello) 551 } else { 552 // from clientReader.ReadMultiBuffer to serverWriter.WriteMultiBufer 553 err = buf.Copy(clientReader, serverWriter, buf.UpdateActivity(timer)) 554 } 555 556 if err != nil { 557 return newError("failed to transfer request payload").Base(err).AtInfo() 558 } 559 560 return nil 561 } 562 563 getResponse := func() error { 564 defer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly) 565 566 bufferWriter := buf.NewBufferedWriter(buf.NewWriter(connection)) 567 if err := encoding.EncodeResponseHeader(bufferWriter, request, responseAddons); err != nil { 568 return newError("failed to encode response header").Base(err).AtWarning() 569 } 570 571 // default: clientWriter := bufferWriter 572 clientWriter := encoding.EncodeBodyAddons(bufferWriter, request, responseAddons) 573 userUUID := account.ID.Bytes() 574 multiBuffer, err1 := serverReader.ReadMultiBuffer() 575 if err1 != nil { 576 return err1 // ... 577 } 578 if requestAddons.Flow == vless.XRV { 579 encoding.XtlsFilterTls(multiBuffer, &numberOfPacketToFilter, &enableXtls, &isTLS12orAbove, &isTLS, &cipher, &remainingServerHello, ctx) 580 multiBuffer = encoding.ReshapeMultiBuffer(ctx, multiBuffer) 581 for i, b := range multiBuffer { 582 multiBuffer[i] = encoding.XtlsPadding(b, encoding.CommandPaddingContinue, &userUUID, isTLS, ctx) 583 } 584 } 585 if err := clientWriter.WriteMultiBuffer(multiBuffer); err != nil { 586 return err // ... 587 } 588 // Flush; bufferWriter.WriteMultiBufer now is bufferWriter.writer.WriteMultiBuffer 589 if err := bufferWriter.SetBuffered(false); err != nil { 590 return newError("failed to write A response payload").Base(err).AtWarning() 591 } 592 593 var err error 594 if rawConn != nil && requestAddons.Flow == vless.XRV { 595 var counter stats.Counter 596 if statConn != nil { 597 counter = statConn.WriteCounter 598 } 599 err = encoding.XtlsWrite(serverReader, clientWriter, timer, netConn, counter, ctx, &numberOfPacketToFilter, 600 &enableXtls, &isTLS12orAbove, &isTLS, &cipher, &remainingServerHello) 601 } else { 602 // from serverReader.ReadMultiBuffer to clientWriter.WriteMultiBufer 603 err = buf.Copy(serverReader, clientWriter, buf.UpdateActivity(timer)) 604 } 605 if err != nil { 606 return newError("failed to transfer response payload").Base(err).AtInfo() 607 } 608 // Indicates the end of response payload. 609 switch responseAddons.Flow { 610 default: 611 } 612 613 return nil 614 } 615 616 if err := task.Run(ctx, task.OnSuccess(postRequest, task.Close(serverWriter)), getResponse); err != nil { 617 common.Interrupt(serverReader) 618 common.Interrupt(serverWriter) 619 return newError("connection ends").Base(err).AtInfo() 620 } 621 622 return nil 623 }