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