github.com/xtls/xray-core@v1.8.12-0.20240518155711-3168d27b0bdb/proxy/vless/encoding/encoding.go (about) 1 package encoding 2 3 //go:generate go run github.com/xtls/xray-core/common/errors/errorgen 4 5 import ( 6 "bytes" 7 "context" 8 "io" 9 10 "github.com/xtls/xray-core/common/buf" 11 "github.com/xtls/xray-core/common/errors" 12 "github.com/xtls/xray-core/common/net" 13 "github.com/xtls/xray-core/common/protocol" 14 "github.com/xtls/xray-core/common/session" 15 "github.com/xtls/xray-core/common/signal" 16 "github.com/xtls/xray-core/features/stats" 17 "github.com/xtls/xray-core/proxy" 18 "github.com/xtls/xray-core/proxy/vless" 19 ) 20 21 const ( 22 Version = byte(0) 23 ) 24 25 var addrParser = protocol.NewAddressParser( 26 protocol.AddressFamilyByte(byte(protocol.AddressTypeIPv4), net.AddressFamilyIPv4), 27 protocol.AddressFamilyByte(byte(protocol.AddressTypeDomain), net.AddressFamilyDomain), 28 protocol.AddressFamilyByte(byte(protocol.AddressTypeIPv6), net.AddressFamilyIPv6), 29 protocol.PortThenAddress(), 30 ) 31 32 // EncodeRequestHeader writes encoded request header into the given writer. 33 func EncodeRequestHeader(writer io.Writer, request *protocol.RequestHeader, requestAddons *Addons) error { 34 buffer := buf.StackNew() 35 defer buffer.Release() 36 37 if err := buffer.WriteByte(request.Version); err != nil { 38 return newError("failed to write request version").Base(err) 39 } 40 41 if _, err := buffer.Write(request.User.Account.(*vless.MemoryAccount).ID.Bytes()); err != nil { 42 return newError("failed to write request user id").Base(err) 43 } 44 45 if err := EncodeHeaderAddons(&buffer, requestAddons); err != nil { 46 return newError("failed to encode request header addons").Base(err) 47 } 48 49 if err := buffer.WriteByte(byte(request.Command)); err != nil { 50 return newError("failed to write request command").Base(err) 51 } 52 53 if request.Command != protocol.RequestCommandMux { 54 if err := addrParser.WriteAddressPort(&buffer, request.Address, request.Port); err != nil { 55 return newError("failed to write request address and port").Base(err) 56 } 57 } 58 59 if _, err := writer.Write(buffer.Bytes()); err != nil { 60 return newError("failed to write request header").Base(err) 61 } 62 63 return nil 64 } 65 66 // DecodeRequestHeader decodes and returns (if successful) a RequestHeader from an input stream. 67 func DecodeRequestHeader(isfb bool, first *buf.Buffer, reader io.Reader, validator *vless.Validator) (*protocol.RequestHeader, *Addons, bool, error) { 68 buffer := buf.StackNew() 69 defer buffer.Release() 70 71 request := new(protocol.RequestHeader) 72 73 if isfb { 74 request.Version = first.Byte(0) 75 } else { 76 if _, err := buffer.ReadFullFrom(reader, 1); err != nil { 77 return nil, nil, false, newError("failed to read request version").Base(err) 78 } 79 request.Version = buffer.Byte(0) 80 } 81 82 switch request.Version { 83 case 0: 84 85 var id [16]byte 86 87 if isfb { 88 copy(id[:], first.BytesRange(1, 17)) 89 } else { 90 buffer.Clear() 91 if _, err := buffer.ReadFullFrom(reader, 16); err != nil { 92 return nil, nil, false, newError("failed to read request user id").Base(err) 93 } 94 copy(id[:], buffer.Bytes()) 95 } 96 97 if request.User = validator.Get(id); request.User == nil { 98 return nil, nil, isfb, newError("invalid request user id") 99 } 100 101 if isfb { 102 first.Advance(17) 103 } 104 105 requestAddons, err := DecodeHeaderAddons(&buffer, reader) 106 if err != nil { 107 return nil, nil, false, newError("failed to decode request header addons").Base(err) 108 } 109 110 buffer.Clear() 111 if _, err := buffer.ReadFullFrom(reader, 1); err != nil { 112 return nil, nil, false, newError("failed to read request command").Base(err) 113 } 114 115 request.Command = protocol.RequestCommand(buffer.Byte(0)) 116 switch request.Command { 117 case protocol.RequestCommandMux: 118 request.Address = net.DomainAddress("v1.mux.cool") 119 request.Port = 0 120 case protocol.RequestCommandTCP, protocol.RequestCommandUDP: 121 if addr, port, err := addrParser.ReadAddressPort(&buffer, reader); err == nil { 122 request.Address = addr 123 request.Port = port 124 } 125 } 126 if request.Address == nil { 127 return nil, nil, false, newError("invalid request address") 128 } 129 return request, requestAddons, false, nil 130 default: 131 return nil, nil, isfb, newError("invalid request version") 132 } 133 } 134 135 // EncodeResponseHeader writes encoded response header into the given writer. 136 func EncodeResponseHeader(writer io.Writer, request *protocol.RequestHeader, responseAddons *Addons) error { 137 buffer := buf.StackNew() 138 defer buffer.Release() 139 140 if err := buffer.WriteByte(request.Version); err != nil { 141 return newError("failed to write response version").Base(err) 142 } 143 144 if err := EncodeHeaderAddons(&buffer, responseAddons); err != nil { 145 return newError("failed to encode response header addons").Base(err) 146 } 147 148 if _, err := writer.Write(buffer.Bytes()); err != nil { 149 return newError("failed to write response header").Base(err) 150 } 151 152 return nil 153 } 154 155 // DecodeResponseHeader decodes and returns (if successful) a ResponseHeader from an input stream. 156 func DecodeResponseHeader(reader io.Reader, request *protocol.RequestHeader) (*Addons, error) { 157 buffer := buf.StackNew() 158 defer buffer.Release() 159 160 if _, err := buffer.ReadFullFrom(reader, 1); err != nil { 161 return nil, newError("failed to read response version").Base(err) 162 } 163 164 if buffer.Byte(0) != request.Version { 165 return nil, newError("unexpected response version. Expecting ", int(request.Version), " but actually ", int(buffer.Byte(0))) 166 } 167 168 responseAddons, err := DecodeHeaderAddons(&buffer, reader) 169 if err != nil { 170 return nil, newError("failed to decode response header addons").Base(err) 171 } 172 173 return responseAddons, nil 174 } 175 176 // XtlsRead filter and read xtls protocol 177 func XtlsRead(reader buf.Reader, writer buf.Writer, timer *signal.ActivityTimer, conn net.Conn, input *bytes.Reader, rawInput *bytes.Buffer, trafficState *proxy.TrafficState, ob *session.Outbound, ctx context.Context) error { 178 err := func() error { 179 for { 180 if trafficState.ReaderSwitchToDirectCopy { 181 var writerConn net.Conn 182 if inbound := session.InboundFromContext(ctx); inbound != nil && inbound.Conn != nil { 183 writerConn = inbound.Conn 184 if inbound.CanSpliceCopy == 2 { 185 inbound.CanSpliceCopy = 1 186 } 187 if ob != nil && ob.CanSpliceCopy == 2 { // ob need to be passed in due to context can change 188 ob.CanSpliceCopy = 1 189 } 190 } 191 return proxy.CopyRawConnIfExist(ctx, conn, writerConn, writer, timer) 192 } 193 buffer, err := reader.ReadMultiBuffer() 194 if !buffer.IsEmpty() { 195 timer.Update() 196 if trafficState.ReaderSwitchToDirectCopy { 197 // XTLS Vision processes struct TLS Conn's input and rawInput 198 if inputBuffer, err := buf.ReadFrom(input); err == nil { 199 if !inputBuffer.IsEmpty() { 200 buffer, _ = buf.MergeMulti(buffer, inputBuffer) 201 } 202 } 203 if rawInputBuffer, err := buf.ReadFrom(rawInput); err == nil { 204 if !rawInputBuffer.IsEmpty() { 205 buffer, _ = buf.MergeMulti(buffer, rawInputBuffer) 206 } 207 } 208 } 209 if werr := writer.WriteMultiBuffer(buffer); werr != nil { 210 return werr 211 } 212 } 213 if err != nil { 214 return err 215 } 216 } 217 }() 218 if err != nil && errors.Cause(err) != io.EOF { 219 return err 220 } 221 return nil 222 } 223 224 // XtlsWrite filter and write xtls protocol 225 func XtlsWrite(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater, conn net.Conn, trafficState *proxy.TrafficState, ob *session.Outbound, ctx context.Context) error { 226 err := func() error { 227 var ct stats.Counter 228 for { 229 buffer, err := reader.ReadMultiBuffer() 230 if trafficState.WriterSwitchToDirectCopy { 231 if inbound := session.InboundFromContext(ctx); inbound != nil { 232 if inbound.CanSpliceCopy == 2 { 233 inbound.CanSpliceCopy = 1 234 } 235 if ob != nil && ob.CanSpliceCopy == 2 { 236 ob.CanSpliceCopy = 1 237 } 238 } 239 rawConn, _, writerCounter := proxy.UnwrapRawConn(conn) 240 writer = buf.NewWriter(rawConn) 241 ct = writerCounter 242 trafficState.WriterSwitchToDirectCopy = false 243 } 244 if !buffer.IsEmpty() { 245 if ct != nil { 246 ct.Add(int64(buffer.Len())) 247 } 248 timer.Update() 249 if werr := writer.WriteMultiBuffer(buffer); werr != nil { 250 return werr 251 } 252 } 253 if err != nil { 254 return err 255 } 256 } 257 }() 258 if err != nil && errors.Cause(err) != io.EOF { 259 return err 260 } 261 return nil 262 }