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