github.com/Uhtred009/v2ray-core-1@v4.31.2+incompatible/proxy/vless/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  	"strconv"
    11  	"time"
    12  
    13  	"v2ray.com/core"
    14  	"v2ray.com/core/common"
    15  	"v2ray.com/core/common/buf"
    16  	"v2ray.com/core/common/errors"
    17  	"v2ray.com/core/common/log"
    18  	"v2ray.com/core/common/net"
    19  	"v2ray.com/core/common/platform"
    20  	"v2ray.com/core/common/protocol"
    21  	"v2ray.com/core/common/retry"
    22  	"v2ray.com/core/common/session"
    23  	"v2ray.com/core/common/signal"
    24  	"v2ray.com/core/common/task"
    25  	"v2ray.com/core/features/dns"
    26  	feature_inbound "v2ray.com/core/features/inbound"
    27  	"v2ray.com/core/features/policy"
    28  	"v2ray.com/core/features/routing"
    29  	"v2ray.com/core/proxy/vless"
    30  	"v2ray.com/core/proxy/vless/encoding"
    31  	"v2ray.com/core/transport/internet"
    32  	"v2ray.com/core/transport/internet/tls"
    33  	"v2ray.com/core/transport/internet/xtls"
    34  )
    35  
    36  var (
    37  	xtls_show = false
    38  )
    39  
    40  func init() {
    41  	common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
    42  		var dc dns.Client
    43  		if err := core.RequireFeatures(ctx, func(d dns.Client) error {
    44  			dc = d
    45  			return nil
    46  		}); err != nil {
    47  			return nil, err
    48  		}
    49  		return New(ctx, config.(*Config), dc)
    50  	}))
    51  
    52  	const defaultFlagValue = "NOT_DEFINED_AT_ALL"
    53  
    54  	xtlsShow := platform.NewEnvFlag("v2ray.vless.xtls.show").GetValue(func() string { return defaultFlagValue })
    55  	if xtlsShow == "true" {
    56  		xtls_show = true
    57  	}
    58  }
    59  
    60  // Handler is an inbound connection handler that handles messages in VLess protocol.
    61  type Handler struct {
    62  	inboundHandlerManager feature_inbound.Manager
    63  	policyManager         policy.Manager
    64  	validator             *vless.Validator
    65  	dns                   dns.Client
    66  	fallbacks             map[string]map[string]*Fallback // or nil
    67  	//regexps               map[string]*regexp.Regexp       // or nil
    68  }
    69  
    70  // New creates a new VLess inbound handler.
    71  func New(ctx context.Context, config *Config, dc dns.Client) (*Handler, error) {
    72  
    73  	v := core.MustFromContext(ctx)
    74  	handler := &Handler{
    75  		inboundHandlerManager: v.GetFeature(feature_inbound.ManagerType()).(feature_inbound.Manager),
    76  		policyManager:         v.GetFeature(policy.ManagerType()).(policy.Manager),
    77  		validator:             new(vless.Validator),
    78  		dns:                   dc,
    79  	}
    80  
    81  	for _, user := range config.Clients {
    82  		u, err := user.ToMemoryUser()
    83  		if err != nil {
    84  			return nil, newError("failed to get VLESS user").Base(err).AtError()
    85  		}
    86  		if err := handler.AddUser(ctx, u); err != nil {
    87  			return nil, newError("failed to initiate user").Base(err).AtError()
    88  		}
    89  	}
    90  
    91  	if config.Fallbacks != nil {
    92  		handler.fallbacks = make(map[string]map[string]*Fallback)
    93  		//handler.regexps = make(map[string]*regexp.Regexp)
    94  		for _, fb := range config.Fallbacks {
    95  			if handler.fallbacks[fb.Alpn] == nil {
    96  				handler.fallbacks[fb.Alpn] = make(map[string]*Fallback)
    97  			}
    98  			handler.fallbacks[fb.Alpn][fb.Path] = fb
    99  			/*
   100  				if fb.Path != "" {
   101  					if r, err := regexp.Compile(fb.Path); err != nil {
   102  						return nil, newError("invalid path regexp").Base(err).AtError()
   103  					} else {
   104  						handler.regexps[fb.Path] = r
   105  					}
   106  				}
   107  			*/
   108  		}
   109  		if handler.fallbacks[""] != nil {
   110  			for alpn, pfb := range handler.fallbacks {
   111  				if alpn != "" { // && alpn != "h2" {
   112  					for path, fb := range handler.fallbacks[""] {
   113  						if pfb[path] == nil {
   114  							pfb[path] = fb
   115  						}
   116  					}
   117  				}
   118  			}
   119  		}
   120  	}
   121  
   122  	return handler, nil
   123  }
   124  
   125  // Close implements common.Closable.Close().
   126  func (h *Handler) Close() error {
   127  	return errors.Combine(common.Close(h.validator))
   128  }
   129  
   130  // AddUser implements proxy.UserManager.AddUser().
   131  func (h *Handler) AddUser(ctx context.Context, u *protocol.MemoryUser) error {
   132  	return h.validator.Add(u)
   133  }
   134  
   135  // RemoveUser implements proxy.UserManager.RemoveUser().
   136  func (h *Handler) RemoveUser(ctx context.Context, e string) error {
   137  	return h.validator.Del(e)
   138  }
   139  
   140  // Network implements proxy.Inbound.Network().
   141  func (*Handler) Network() []net.Network {
   142  	return []net.Network{net.Network_TCP}
   143  }
   144  
   145  // Process implements proxy.Inbound.Process().
   146  func (h *Handler) Process(ctx context.Context, network net.Network, connection internet.Connection, dispatcher routing.Dispatcher) error {
   147  
   148  	sid := session.ExportIDToError(ctx)
   149  
   150  	iConn := connection
   151  	if statConn, ok := iConn.(*internet.StatCouterConnection); ok {
   152  		iConn = statConn.Connection
   153  	}
   154  
   155  	sessionPolicy := h.policyManager.ForLevel(0)
   156  	if err := connection.SetReadDeadline(time.Now().Add(sessionPolicy.Timeouts.Handshake)); err != nil {
   157  		return newError("unable to set read deadline").Base(err).AtWarning()
   158  	}
   159  
   160  	first := buf.New()
   161  	defer first.Release()
   162  
   163  	firstLen, _ := first.ReadFrom(connection)
   164  	newError("firstLen = ", firstLen).AtInfo().WriteToLog(sid)
   165  
   166  	reader := &buf.BufferedReader{
   167  		Reader: buf.NewReader(connection),
   168  		Buffer: buf.MultiBuffer{first},
   169  	}
   170  
   171  	var request *protocol.RequestHeader
   172  	var requestAddons *encoding.Addons
   173  	var err error
   174  
   175  	apfb := h.fallbacks
   176  	isfb := apfb != nil
   177  
   178  	if isfb && firstLen < 18 {
   179  		err = newError("fallback directly")
   180  	} else {
   181  		request, requestAddons, err, isfb = encoding.DecodeRequestHeader(isfb, first, reader, h.validator)
   182  	}
   183  
   184  	if err != nil {
   185  
   186  		if isfb {
   187  			if err := connection.SetReadDeadline(time.Time{}); err != nil {
   188  				newError("unable to set back read deadline").Base(err).AtWarning().WriteToLog(sid)
   189  			}
   190  			newError("fallback starts").Base(err).AtInfo().WriteToLog(sid)
   191  
   192  			alpn := ""
   193  			if len(apfb) > 1 || apfb[""] == nil {
   194  				if tlsConn, ok := iConn.(*tls.Conn); ok {
   195  					alpn = tlsConn.ConnectionState().NegotiatedProtocol
   196  					newError("realAlpn = " + alpn).AtInfo().WriteToLog(sid)
   197  				} else if xtlsConn, ok := iConn.(*xtls.Conn); ok {
   198  					alpn = xtlsConn.ConnectionState().NegotiatedProtocol
   199  					newError("realAlpn = " + alpn).AtInfo().WriteToLog(sid)
   200  				}
   201  				if apfb[alpn] == nil {
   202  					alpn = ""
   203  				}
   204  			}
   205  			pfb := apfb[alpn]
   206  			if pfb == nil {
   207  				return newError(`failed to find the default "alpn" config`).AtWarning()
   208  			}
   209  
   210  			path := ""
   211  			if len(pfb) > 1 || pfb[""] == nil {
   212  				/*
   213  					if lines := bytes.Split(firstBytes, []byte{'\r', '\n'}); len(lines) > 1 {
   214  						if s := bytes.Split(lines[0], []byte{' '}); len(s) == 3 {
   215  							if len(s[0]) < 8 && len(s[1]) > 0 && len(s[2]) == 8 {
   216  								newError("realPath = " + string(s[1])).AtInfo().WriteToLog(sid)
   217  								for _, fb := range pfb {
   218  									if fb.Path != "" && h.regexps[fb.Path].Match(s[1]) {
   219  										path = fb.Path
   220  										break
   221  									}
   222  								}
   223  							}
   224  						}
   225  					}
   226  				*/
   227  				if firstLen >= 18 && first.Byte(4) != '*' { // not h2c
   228  					firstBytes := first.Bytes()
   229  					for i := 4; i <= 8; i++ { // 5 -> 9
   230  						if firstBytes[i] == '/' && firstBytes[i-1] == ' ' {
   231  							search := len(firstBytes)
   232  							if search > 64 {
   233  								search = 64 // up to about 60
   234  							}
   235  							for j := i + 1; j < search; j++ {
   236  								k := firstBytes[j]
   237  								if k == '\r' || k == '\n' { // avoid logging \r or \n
   238  									break
   239  								}
   240  								if k == ' ' {
   241  									path = string(firstBytes[i:j])
   242  									newError("realPath = " + path).AtInfo().WriteToLog(sid)
   243  									if pfb[path] == nil {
   244  										path = ""
   245  									}
   246  									break
   247  								}
   248  							}
   249  							break
   250  						}
   251  					}
   252  				}
   253  			}
   254  			fb := pfb[path]
   255  			if fb == nil {
   256  				return newError(`failed to find the default "path" config`).AtWarning()
   257  			}
   258  
   259  			ctx, cancel := context.WithCancel(ctx)
   260  			timer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle)
   261  			ctx = policy.ContextWithBufferPolicy(ctx, sessionPolicy.Buffer)
   262  
   263  			var conn net.Conn
   264  			if err := retry.ExponentialBackoff(5, 100).On(func() error {
   265  				var dialer net.Dialer
   266  				conn, err = dialer.DialContext(ctx, fb.Type, fb.Dest)
   267  				if err != nil {
   268  					return err
   269  				}
   270  				return nil
   271  			}); err != nil {
   272  				return newError("failed to dial to " + fb.Dest).Base(err).AtWarning()
   273  			}
   274  			defer conn.Close() // nolint: errcheck
   275  
   276  			serverReader := buf.NewReader(conn)
   277  			serverWriter := buf.NewWriter(conn)
   278  
   279  			postRequest := func() error {
   280  				defer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly)
   281  				if fb.Xver != 0 {
   282  					remoteAddr, remotePort, err := net.SplitHostPort(connection.RemoteAddr().String())
   283  					if err != nil {
   284  						return err
   285  					}
   286  					localAddr, localPort, err := net.SplitHostPort(connection.LocalAddr().String())
   287  					if err != nil {
   288  						return err
   289  					}
   290  					ipv4 := true
   291  					for i := 0; i < len(remoteAddr); i++ {
   292  						if remoteAddr[i] == ':' {
   293  							ipv4 = false
   294  							break
   295  						}
   296  					}
   297  					pro := buf.New()
   298  					defer pro.Release()
   299  					switch fb.Xver {
   300  					case 1:
   301  						if ipv4 {
   302  							pro.Write([]byte("PROXY TCP4 " + remoteAddr + " " + localAddr + " " + remotePort + " " + localPort + "\r\n"))
   303  						} else {
   304  							pro.Write([]byte("PROXY TCP6 " + remoteAddr + " " + localAddr + " " + remotePort + " " + localPort + "\r\n"))
   305  						}
   306  					case 2:
   307  						pro.Write([]byte("\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A\x21")) // signature + v2 + PROXY
   308  						if ipv4 {
   309  							pro.Write([]byte("\x11\x00\x0C")) // AF_INET + STREAM + 12 bytes
   310  							pro.Write(net.ParseIP(remoteAddr).To4())
   311  							pro.Write(net.ParseIP(localAddr).To4())
   312  						} else {
   313  							pro.Write([]byte("\x21\x00\x24")) // AF_INET6 + STREAM + 36 bytes
   314  							pro.Write(net.ParseIP(remoteAddr).To16())
   315  							pro.Write(net.ParseIP(localAddr).To16())
   316  						}
   317  						p1, _ := strconv.ParseUint(remotePort, 10, 16)
   318  						p2, _ := strconv.ParseUint(localPort, 10, 16)
   319  						pro.Write([]byte{byte(p1 >> 8), byte(p1), byte(p2 >> 8), byte(p2)})
   320  					}
   321  					if err := serverWriter.WriteMultiBuffer(buf.MultiBuffer{pro}); err != nil {
   322  						return newError("failed to set PROXY protocol v", fb.Xver).Base(err).AtWarning()
   323  					}
   324  				}
   325  				if err := buf.Copy(reader, serverWriter, buf.UpdateActivity(timer)); err != nil {
   326  					return newError("failed to fallback request payload").Base(err).AtInfo()
   327  				}
   328  				return nil
   329  			}
   330  
   331  			writer := buf.NewWriter(connection)
   332  
   333  			getResponse := func() error {
   334  				defer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly)
   335  				if err := buf.Copy(serverReader, writer, buf.UpdateActivity(timer)); err != nil {
   336  					return newError("failed to deliver response payload").Base(err).AtInfo()
   337  				}
   338  				return nil
   339  			}
   340  
   341  			if err := task.Run(ctx, task.OnSuccess(postRequest, task.Close(serverWriter)), task.OnSuccess(getResponse, task.Close(writer))); err != nil {
   342  				common.Interrupt(serverReader)
   343  				common.Interrupt(serverWriter)
   344  				return newError("fallback ends").Base(err).AtInfo()
   345  			}
   346  			return nil
   347  		}
   348  
   349  		if errors.Cause(err) != io.EOF {
   350  			log.Record(&log.AccessMessage{
   351  				From:   connection.RemoteAddr(),
   352  				To:     "",
   353  				Status: log.AccessRejected,
   354  				Reason: err,
   355  			})
   356  			err = newError("invalid request from ", connection.RemoteAddr()).Base(err).AtWarning()
   357  		}
   358  		return err
   359  	}
   360  
   361  	if err := connection.SetReadDeadline(time.Time{}); err != nil {
   362  		newError("unable to set back read deadline").Base(err).AtWarning().WriteToLog(sid)
   363  	}
   364  	newError("received request for ", request.Destination()).AtInfo().WriteToLog(sid)
   365  
   366  	inbound := session.InboundFromContext(ctx)
   367  	if inbound == nil {
   368  		panic("no inbound metadata")
   369  	}
   370  	inbound.User = request.User
   371  
   372  	account := request.User.Account.(*vless.MemoryAccount)
   373  
   374  	responseAddons := &encoding.Addons{
   375  		//Flow: requestAddons.Flow,
   376  	}
   377  
   378  	switch requestAddons.Flow {
   379  	case vless.XRO, vless.XRD:
   380  		if account.Flow == requestAddons.Flow {
   381  			switch request.Command {
   382  			case protocol.RequestCommandMux:
   383  				return newError(requestAddons.Flow + " doesn't support Mux").AtWarning()
   384  			case protocol.RequestCommandUDP:
   385  				return newError(requestAddons.Flow + " doesn't support UDP").AtWarning()
   386  			case protocol.RequestCommandTCP:
   387  				if xtlsConn, ok := iConn.(*xtls.Conn); ok {
   388  					xtlsConn.RPRX = true
   389  					xtlsConn.SHOW = xtls_show
   390  					xtlsConn.MARK = "XTLS"
   391  					if requestAddons.Flow == vless.XRD {
   392  						xtlsConn.DirectMode = true
   393  					}
   394  				} else {
   395  					return newError(`failed to use ` + requestAddons.Flow + `, maybe "security" is not "xtls"`).AtWarning()
   396  				}
   397  			}
   398  		} else {
   399  			return newError(account.ID.String() + " is not able to use " + requestAddons.Flow).AtWarning()
   400  		}
   401  	case "":
   402  	default:
   403  		return newError("unknown request flow " + requestAddons.Flow).AtWarning()
   404  	}
   405  
   406  	if request.Command != protocol.RequestCommandMux {
   407  		ctx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{
   408  			From:   connection.RemoteAddr(),
   409  			To:     request.Destination(),
   410  			Status: log.AccessAccepted,
   411  			Reason: "",
   412  			Email:  request.User.Email,
   413  		})
   414  	}
   415  
   416  	sessionPolicy = h.policyManager.ForLevel(request.User.Level)
   417  	ctx, cancel := context.WithCancel(ctx)
   418  	timer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle)
   419  	ctx = policy.ContextWithBufferPolicy(ctx, sessionPolicy.Buffer)
   420  
   421  	link, err := dispatcher.Dispatch(ctx, request.Destination())
   422  	if err != nil {
   423  		return newError("failed to dispatch request to ", request.Destination()).Base(err).AtWarning()
   424  	}
   425  
   426  	serverReader := link.Reader // .(*pipe.Reader)
   427  	serverWriter := link.Writer // .(*pipe.Writer)
   428  
   429  	postRequest := func() error {
   430  		defer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly)
   431  
   432  		// default: clientReader := reader
   433  		clientReader := encoding.DecodeBodyAddons(reader, request, requestAddons)
   434  
   435  		// from clientReader.ReadMultiBuffer to serverWriter.WriteMultiBufer
   436  		if err := buf.Copy(clientReader, serverWriter, buf.UpdateActivity(timer)); err != nil {
   437  			return newError("failed to transfer request payload").Base(err).AtInfo()
   438  		}
   439  
   440  		return nil
   441  	}
   442  
   443  	getResponse := func() error {
   444  		defer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly)
   445  
   446  		bufferWriter := buf.NewBufferedWriter(buf.NewWriter(connection))
   447  		if err := encoding.EncodeResponseHeader(bufferWriter, request, responseAddons); err != nil {
   448  			return newError("failed to encode response header").Base(err).AtWarning()
   449  		}
   450  
   451  		// default: clientWriter := bufferWriter
   452  		clientWriter := encoding.EncodeBodyAddons(bufferWriter, request, responseAddons)
   453  		{
   454  			multiBuffer, err := serverReader.ReadMultiBuffer()
   455  			if err != nil {
   456  				return err // ...
   457  			}
   458  			if err := clientWriter.WriteMultiBuffer(multiBuffer); err != nil {
   459  				return err // ...
   460  			}
   461  		}
   462  
   463  		// Flush; bufferWriter.WriteMultiBufer now is bufferWriter.writer.WriteMultiBuffer
   464  		if err := bufferWriter.SetBuffered(false); err != nil {
   465  			return newError("failed to write A response payload").Base(err).AtWarning()
   466  		}
   467  
   468  		// from serverReader.ReadMultiBuffer to clientWriter.WriteMultiBufer
   469  		if err := buf.Copy(serverReader, clientWriter, buf.UpdateActivity(timer)); err != nil {
   470  			return newError("failed to transfer response payload").Base(err).AtInfo()
   471  		}
   472  
   473  		// Indicates the end of response payload.
   474  		switch responseAddons.Flow {
   475  		default:
   476  
   477  		}
   478  
   479  		return nil
   480  	}
   481  
   482  	if err := task.Run(ctx, task.OnSuccess(postRequest, task.Close(serverWriter)), getResponse); err != nil {
   483  		common.Interrupt(serverReader)
   484  		common.Interrupt(serverWriter)
   485  		return newError("connection ends").Base(err).AtInfo()
   486  	}
   487  
   488  	return nil
   489  }