github.com/xtls/xray-core@v1.8.12-0.20240518155711-3168d27b0bdb/proxy/vless/encoding/addons.go (about) 1 package encoding 2 3 import ( 4 "context" 5 "io" 6 7 "github.com/xtls/xray-core/common/buf" 8 "github.com/xtls/xray-core/common/protocol" 9 "github.com/xtls/xray-core/proxy" 10 "github.com/xtls/xray-core/proxy/vless" 11 "google.golang.org/protobuf/proto" 12 ) 13 14 func EncodeHeaderAddons(buffer *buf.Buffer, addons *Addons) error { 15 switch addons.Flow { 16 case vless.XRV: 17 bytes, err := proto.Marshal(addons) 18 if err != nil { 19 return newError("failed to marshal addons protobuf value").Base(err) 20 } 21 if err := buffer.WriteByte(byte(len(bytes))); err != nil { 22 return newError("failed to write addons protobuf length").Base(err) 23 } 24 if _, err := buffer.Write(bytes); err != nil { 25 return newError("failed to write addons protobuf value").Base(err) 26 } 27 default: 28 if err := buffer.WriteByte(0); err != nil { 29 return newError("failed to write addons protobuf length").Base(err) 30 } 31 } 32 33 return nil 34 } 35 36 func DecodeHeaderAddons(buffer *buf.Buffer, reader io.Reader) (*Addons, error) { 37 addons := new(Addons) 38 buffer.Clear() 39 if _, err := buffer.ReadFullFrom(reader, 1); err != nil { 40 return nil, newError("failed to read addons protobuf length").Base(err) 41 } 42 43 if length := int32(buffer.Byte(0)); length != 0 { 44 buffer.Clear() 45 if _, err := buffer.ReadFullFrom(reader, length); err != nil { 46 return nil, newError("failed to read addons protobuf value").Base(err) 47 } 48 49 if err := proto.Unmarshal(buffer.Bytes(), addons); err != nil { 50 return nil, newError("failed to unmarshal addons protobuf value").Base(err) 51 } 52 53 // Verification. 54 switch addons.Flow { 55 default: 56 } 57 } 58 59 return addons, nil 60 } 61 62 // EncodeBodyAddons returns a Writer that auto-encrypt content written by caller. 63 func EncodeBodyAddons(writer io.Writer, request *protocol.RequestHeader, requestAddons *Addons, state *proxy.TrafficState, context context.Context) buf.Writer { 64 if request.Command == protocol.RequestCommandUDP { 65 return NewMultiLengthPacketWriter(writer.(buf.Writer)) 66 } 67 w := buf.NewWriter(writer) 68 if requestAddons.Flow == vless.XRV { 69 w = proxy.NewVisionWriter(w, state, context) 70 } 71 return w 72 } 73 74 // DecodeBodyAddons returns a Reader from which caller can fetch decrypted body. 75 func DecodeBodyAddons(reader io.Reader, request *protocol.RequestHeader, addons *Addons) buf.Reader { 76 switch addons.Flow { 77 default: 78 if request.Command == protocol.RequestCommandUDP { 79 return NewLengthPacketReader(reader) 80 } 81 } 82 return buf.NewReader(reader) 83 } 84 85 func NewMultiLengthPacketWriter(writer buf.Writer) *MultiLengthPacketWriter { 86 return &MultiLengthPacketWriter{ 87 Writer: writer, 88 } 89 } 90 91 type MultiLengthPacketWriter struct { 92 buf.Writer 93 } 94 95 func (w *MultiLengthPacketWriter) WriteMultiBuffer(mb buf.MultiBuffer) error { 96 defer buf.ReleaseMulti(mb) 97 mb2Write := make(buf.MultiBuffer, 0, len(mb)+1) 98 for _, b := range mb { 99 length := b.Len() 100 if length == 0 || length+2 > buf.Size { 101 continue 102 } 103 eb := buf.New() 104 if err := eb.WriteByte(byte(length >> 8)); err != nil { 105 eb.Release() 106 continue 107 } 108 if err := eb.WriteByte(byte(length)); err != nil { 109 eb.Release() 110 continue 111 } 112 if _, err := eb.Write(b.Bytes()); err != nil { 113 eb.Release() 114 continue 115 } 116 mb2Write = append(mb2Write, eb) 117 } 118 if mb2Write.IsEmpty() { 119 return nil 120 } 121 return w.Writer.WriteMultiBuffer(mb2Write) 122 } 123 124 func NewLengthPacketWriter(writer io.Writer) *LengthPacketWriter { 125 return &LengthPacketWriter{ 126 Writer: writer, 127 cache: make([]byte, 0, 65536), 128 } 129 } 130 131 type LengthPacketWriter struct { 132 io.Writer 133 cache []byte 134 } 135 136 func (w *LengthPacketWriter) WriteMultiBuffer(mb buf.MultiBuffer) error { 137 length := mb.Len() // none of mb is nil 138 // fmt.Println("Write", length) 139 if length == 0 { 140 return nil 141 } 142 defer func() { 143 w.cache = w.cache[:0] 144 }() 145 w.cache = append(w.cache, byte(length>>8), byte(length)) 146 for i, b := range mb { 147 w.cache = append(w.cache, b.Bytes()...) 148 b.Release() 149 mb[i] = nil 150 } 151 if _, err := w.Write(w.cache); err != nil { 152 return newError("failed to write a packet").Base(err) 153 } 154 return nil 155 } 156 157 func NewLengthPacketReader(reader io.Reader) *LengthPacketReader { 158 return &LengthPacketReader{ 159 Reader: reader, 160 cache: make([]byte, 2), 161 } 162 } 163 164 type LengthPacketReader struct { 165 io.Reader 166 cache []byte 167 } 168 169 func (r *LengthPacketReader) ReadMultiBuffer() (buf.MultiBuffer, error) { 170 if _, err := io.ReadFull(r.Reader, r.cache); err != nil { // maybe EOF 171 return nil, newError("failed to read packet length").Base(err) 172 } 173 length := int32(r.cache[0])<<8 | int32(r.cache[1]) 174 // fmt.Println("Read", length) 175 mb := make(buf.MultiBuffer, 0, length/buf.Size+1) 176 for length > 0 { 177 size := length 178 if size > buf.Size { 179 size = buf.Size 180 } 181 length -= size 182 b := buf.New() 183 if _, err := b.ReadFullFrom(r.Reader, size); err != nil { 184 return nil, newError("failed to read packet payload").Base(err) 185 } 186 mb = append(mb, b) 187 } 188 return mb, nil 189 }