From 318b3524c3702b9faae77388e46826d5c349ee76 Mon Sep 17 00:00:00 2001 From: wwqgtxx Date: Tue, 9 Sep 2025 15:16:57 +0800 Subject: [PATCH] chore: better handwritten addons parsing --- transport/vless/addons.go | 57 ++++++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 18 deletions(-) diff --git a/transport/vless/addons.go b/transport/vless/addons.go index 2257adeb..05aa7646 100644 --- a/transport/vless/addons.go +++ b/transport/vless/addons.go @@ -11,35 +11,48 @@ func ReadAddons(data []byte) (*Addons, error) { reader := bytes.NewReader(data) var addons Addons for reader.Len() > 0 { - protoHeader, err := reader.ReadByte() + tag, err := binary.ReadUvarint(reader) if err != nil { return nil, err } - switch protoHeader { - case (1 << 3) | 2: - flowLen, err := binary.ReadUvarint(reader) + number, typ := int32(tag>>3), int8(tag&7) + switch typ { + case 0: // VARINT + _, err = binary.ReadUvarint(reader) if err != nil { return nil, err } - flowBytes := make([]byte, flowLen) - _, err = io.ReadFull(reader, flowBytes) + case 5: // I32 + var i32 [4]byte + _, err = io.ReadFull(reader, i32[:]) if err != nil { return nil, err } - addons.Flow = string(flowBytes) - case (2 << 3) | 2: - seedLen, err := binary.ReadUvarint(reader) + case 1: // I64 + var i64 [8]byte + _, err = io.ReadFull(reader, i64[:]) if err != nil { return nil, err } - seedBytes := make([]byte, seedLen) - _, err = io.ReadFull(reader, seedBytes) + case 2: // LEN + var bytesLen uint64 + bytesLen, err = binary.ReadUvarint(reader) if err != nil { return nil, err } - addons.Seed = seedBytes - default: - return nil, fmt.Errorf("unknown protobuf message header: %v", protoHeader) + bytesData := make([]byte, bytesLen) + _, err = io.ReadFull(reader, bytesData) + if err != nil { + return nil, err + } + switch number { + case 1: + addons.Flow = string(bytesData) + case 2: + addons.Seed = bytesData + } + default: // group (3,4) has been deprecated we unneeded support + return nil, fmt.Errorf("unknown protobuf message tag: %v", tag) } } return &addons, nil @@ -48,14 +61,22 @@ func ReadAddons(data []byte) (*Addons, error) { func WriteAddons(addons *Addons) []byte { var writer bytes.Buffer if len(addons.Flow) > 0 { - writer.WriteByte((1 << 3) | 2) - writer.Write(binary.AppendUvarint(nil, uint64(len(addons.Flow)))) + WriteUvarint(&writer, (1<<3)|2) // (field << 3) bit-or wire_type encoded as uint32 varint + WriteUvarint(&writer, uint64(len(addons.Flow))) writer.WriteString(addons.Flow) } if len(addons.Seed) > 0 { - writer.WriteByte((2 << 3) | 2) - writer.Write(binary.AppendUvarint(nil, uint64(len(addons.Seed)))) + WriteUvarint(&writer, (2<<3)|2) // (field << 3) bit-or wire_type encoded as uint32 varint + WriteUvarint(&writer, uint64(len(addons.Seed))) writer.Write(addons.Seed) } return writer.Bytes() } + +func WriteUvarint(writer *bytes.Buffer, x uint64) { + for x >= 0x80 { + writer.WriteByte(byte(x) | 0x80) + x >>= 7 + } + writer.WriteByte(byte(x)) +}