github.com/xmplusdev/xray-core@v1.8.10/proxy/vless/encoding/encoding.go (about) 1 package encoding 2 3 //go:generate go run github.com/xmplusdev/xray-core/common/errors/errorgen 4 5 import ( 6 "bytes" 7 "context" 8 "io" 9 10 "github.com/xmplusdev/xray-core/common/buf" 11 "github.com/xmplusdev/xray-core/common/errors" 12 "github.com/xmplusdev/xray-core/common/net" 13 "github.com/xmplusdev/xray-core/common/protocol" 14 "github.com/xmplusdev/xray-core/common/session" 15 "github.com/xmplusdev/xray-core/common/signal" 16 "github.com/xmplusdev/xray-core/features/stats" 17 "github.com/xmplusdev/xray-core/proxy" 18 "github.com/xmplusdev/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.ActivityUpdater, conn net.Conn, input *bytes.Reader, rawInput *bytes.Buffer, trafficState *proxy.TrafficState, 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 // force the value to 1, don't use setter 186 } 187 } 188 return proxy.CopyRawConnIfExist(ctx, conn, writerConn, writer, timer) 189 } 190 buffer, err := reader.ReadMultiBuffer() 191 if !buffer.IsEmpty() { 192 timer.Update() 193 if trafficState.ReaderSwitchToDirectCopy { 194 // XTLS Vision processes struct TLS Conn's input and rawInput 195 if inputBuffer, err := buf.ReadFrom(input); err == nil { 196 if !inputBuffer.IsEmpty() { 197 buffer, _ = buf.MergeMulti(buffer, inputBuffer) 198 } 199 } 200 if rawInputBuffer, err := buf.ReadFrom(rawInput); err == nil { 201 if !rawInputBuffer.IsEmpty() { 202 buffer, _ = buf.MergeMulti(buffer, rawInputBuffer) 203 } 204 } 205 } 206 if werr := writer.WriteMultiBuffer(buffer); werr != nil { 207 return werr 208 } 209 } 210 if err != nil { 211 return err 212 } 213 } 214 }() 215 if err != nil && errors.Cause(err) != io.EOF { 216 return err 217 } 218 return nil 219 } 220 221 // XtlsWrite filter and write xtls protocol 222 func XtlsWrite(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater, conn net.Conn, trafficState *proxy.TrafficState, ctx context.Context) error { 223 err := func() error { 224 var ct stats.Counter 225 for { 226 buffer, err := reader.ReadMultiBuffer() 227 if trafficState.WriterSwitchToDirectCopy { 228 if inbound := session.InboundFromContext(ctx); inbound != nil && inbound.CanSpliceCopy == 2 { 229 inbound.CanSpliceCopy = 1 // force the value to 1, don't use setter 230 } 231 rawConn, _, writerCounter := proxy.UnwrapRawConn(conn) 232 writer = buf.NewWriter(rawConn) 233 ct = writerCounter 234 trafficState.WriterSwitchToDirectCopy = false 235 } 236 if !buffer.IsEmpty() { 237 if ct != nil { 238 ct.Add(int64(buffer.Len())) 239 } 240 timer.Update() 241 if werr := writer.WriteMultiBuffer(buffer); werr != nil { 242 return werr 243 } 244 } 245 if err != nil { 246 return err 247 } 248 } 249 }() 250 if err != nil && errors.Cause(err) != io.EOF { 251 return err 252 } 253 return nil 254 }