diff --git a/infra/conf/vless.go b/infra/conf/vless.go index 00f2f394d..2fe85c76b 100644 --- a/infra/conf/vless.go +++ b/infra/conf/vless.go @@ -35,7 +35,7 @@ func (c *VLessInboundConfig) Build() (proto.Message, error) { config := new(inbound.Config) if len(c.Clients) == 0 { - return nil, newError(`VLESS settings: "clients" is empty`) + //return nil, newError(`VLESS settings: "clients" is empty`) } config.Clients = make([]*protocol.User, len(c.Clients)) for idx, rawUser := range c.Clients { diff --git a/proxy/vless/encoding/encoding.go b/proxy/vless/encoding/encoding.go index b56b30efb..99e466aef 100644 --- a/proxy/vless/encoding/encoding.go +++ b/proxy/vless/encoding/encoding.go @@ -60,49 +60,53 @@ func EncodeRequestHeader(writer io.Writer, request *protocol.RequestHeader, requ } // DecodeRequestHeader decodes and returns (if successful) a RequestHeader from an input stream. -func DecodeRequestHeader(reader io.Reader, validator *vless.Validator) (*protocol.RequestHeader, *Addons, error, *buf.Buffer) { +func DecodeRequestHeader(isfb bool, first *buf.Buffer, reader io.Reader, validator *vless.Validator) (*protocol.RequestHeader, *Addons, error, bool) { buffer := buf.StackNew() defer buffer.Release() - pre := buf.New() + request := new(protocol.RequestHeader) - if _, err := buffer.ReadFullFrom(reader, 1); err != nil { - pre.Write(buffer.Bytes()) - return nil, nil, newError("failed to read request version").Base(err), pre + if isfb { + request.Version = first.Byte(0) + } else { + if _, err := buffer.ReadFullFrom(reader, 1); err != nil { + return nil, nil, newError("failed to read request version").Base(err), false + } + request.Version = buffer.Byte(0) } - request := &protocol.RequestHeader{ - Version: buffer.Byte(0), - } - - pre.Write(buffer.Bytes()) - switch request.Version { case 0: - buffer.Clear() - if _, err := buffer.ReadFullFrom(reader, protocol.IDBytesLen); err != nil { - pre.Write(buffer.Bytes()) - return nil, nil, newError("failed to read request user id").Base(err), pre + var id [16]byte + + if isfb { + copy(id[:], first.BytesRange(1, 17)) + } else { + buffer.Clear() + if _, err := buffer.ReadFullFrom(reader, 16); err != nil { + return nil, nil, newError("failed to read request user id").Base(err), false + } + copy(id[:], buffer.Bytes()) } - var id [16]byte - copy(id[:], buffer.Bytes()) - if request.User = validator.Get(id); request.User == nil { - pre.Write(buffer.Bytes()) - return nil, nil, newError("invalid request user id"), pre + return nil, nil, newError("invalid request user id"), isfb + } + + if isfb { + first.Advance(17) } requestAddons, err := DecodeHeaderAddons(&buffer, reader) if err != nil { - return nil, nil, newError("failed to decode request header addons").Base(err), nil + return nil, nil, newError("failed to decode request header addons").Base(err), false } buffer.Clear() if _, err := buffer.ReadFullFrom(reader, 1); err != nil { - return nil, nil, newError("failed to read request command").Base(err), nil + return nil, nil, newError("failed to read request command").Base(err), false } request.Command = protocol.RequestCommand(buffer.Byte(0)) @@ -118,14 +122,14 @@ func DecodeRequestHeader(reader io.Reader, validator *vless.Validator) (*protoco } if request.Address == nil { - return nil, nil, newError("invalid request address"), nil + return nil, nil, newError("invalid request address"), false } - return request, requestAddons, nil, nil + return request, requestAddons, nil, false default: - return nil, nil, newError("invalid request version"), pre + return nil, nil, newError("invalid request version"), isfb } diff --git a/proxy/vless/encoding/encoding_test.go b/proxy/vless/encoding/encoding_test.go index 1ca2cd088..12c9e2b57 100644 --- a/proxy/vless/encoding/encoding_test.go +++ b/proxy/vless/encoding/encoding_test.go @@ -46,7 +46,7 @@ func TestRequestSerialization(t *testing.T) { Validator := new(vless.Validator) Validator.Add(user) - actualRequest, actualAddons, err, _ := DecodeRequestHeader(&buffer, Validator) + actualRequest, actualAddons, err, _ := DecodeRequestHeader(false, nil, &buffer, Validator) common.Must(err) if r := cmp.Diff(actualRequest, expectedRequest, cmp.AllowUnexported(protocol.ID{})); r != "" { @@ -83,7 +83,7 @@ func TestInvalidRequest(t *testing.T) { Validator := new(vless.Validator) Validator.Add(user) - _, _, err, _ := DecodeRequestHeader(&buffer, Validator) + _, _, err, _ := DecodeRequestHeader(false, nil, &buffer, Validator) if err == nil { t.Error("nil error") } @@ -114,7 +114,7 @@ func TestMuxRequest(t *testing.T) { Validator := new(vless.Validator) Validator.Add(user) - actualRequest, actualAddons, err, _ := DecodeRequestHeader(&buffer, Validator) + actualRequest, actualAddons, err, _ := DecodeRequestHeader(false, nil, &buffer, Validator) common.Must(err) if r := cmp.Diff(actualRequest, expectedRequest, cmp.AllowUnexported(protocol.ID{})); r != "" { diff --git a/proxy/vless/inbound/inbound.go b/proxy/vless/inbound/inbound.go index 803fce33f..cb0439cb7 100644 --- a/proxy/vless/inbound/inbound.go +++ b/proxy/vless/inbound/inbound.go @@ -171,7 +171,6 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection i var request *protocol.RequestHeader var requestAddons *encoding.Addons var err error - var pre *buf.Buffer isfb := false apfb := h.fallbacks @@ -182,12 +181,7 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection i if isfb && firstLen < 18 { err = newError("fallback directly") } else { - request, requestAddons, err, pre = encoding.DecodeRequestHeader(reader, h.validator) - if pre != nil { - defer pre.Release() - } else { - isfb = false - } + request, requestAddons, err, isfb = encoding.DecodeRequestHeader(isfb, first, reader, h.validator) } if err != nil { @@ -233,13 +227,13 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection i } } */ - if pre != nil && pre.Len() == 1 && first.Byte(3) != '*' { // firstLen >= 18 && invalid request version && not h2c + if firstLen >= 18 && first.Byte(4) != '*' { // not h2c firstBytes := first.Bytes() - for i := 3; i <= 7; i++ { // 5 -> 9 + for i := 4; i <= 8; i++ { // 5 -> 9 if firstBytes[i] == '/' && firstBytes[i-1] == ' ' { search := len(firstBytes) if search > 64 { - search = 64 // up to 60 + search = 64 // up to about 60 } for j := i + 1; j < search; j++ { k := firstBytes[j] @@ -331,11 +325,6 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection i return newError("failed to set PROXY protocol v", fb.Xver).Base(err).AtWarning() } } - if pre != nil && pre.Len() > 0 { - if err := serverWriter.WriteMultiBuffer(buf.MultiBuffer{pre}); err != nil { - return newError("failed to fallback request pre").Base(err).AtWarning() - } - } if err := buf.Copy(reader, serverWriter, buf.UpdateActivity(timer)); err != nil { return newError("failed to fallback request payload").Base(err).AtInfo() } diff --git a/proxy/vless/outbound/outbound.go b/proxy/vless/outbound/outbound.go index 3be027783..825464c91 100644 --- a/proxy/vless/outbound/outbound.go +++ b/proxy/vless/outbound/outbound.go @@ -133,7 +133,7 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte return newError(vless.XRO + " doesn't support Mux").AtWarning() case protocol.RequestCommandUDP: if requestAddons.Flow == vless.XRO && request.Port == 443 { - return newError(vless.XRO + " stopped UDP/443").AtWarning() + return newError(vless.XRO + " stopped UDP/443").AtInfo() } requestAddons.Flow = "" case protocol.RequestCommandTCP: