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