github.com/imannamdari/v2ray-core/v5@v5.0.5/proxy/vless/encoding/encoding.go (about) 1 package encoding 2 3 //go:generate go run github.com/imannamdari/v2ray-core/v5/common/errors/errorgen 4 5 import ( 6 "io" 7 8 "github.com/imannamdari/v2ray-core/v5/common/buf" 9 "github.com/imannamdari/v2ray-core/v5/common/net" 10 "github.com/imannamdari/v2ray-core/v5/common/protocol" 11 "github.com/imannamdari/v2ray-core/v5/proxy/vless" 12 ) 13 14 const ( 15 Version = byte(0) 16 ) 17 18 var addrParser = protocol.NewAddressParser( 19 protocol.AddressFamilyByte(byte(protocol.AddressTypeIPv4), net.AddressFamilyIPv4), 20 protocol.AddressFamilyByte(byte(protocol.AddressTypeDomain), net.AddressFamilyDomain), 21 protocol.AddressFamilyByte(byte(protocol.AddressTypeIPv6), net.AddressFamilyIPv6), 22 protocol.PortThenAddress(), 23 ) 24 25 // EncodeRequestHeader writes encoded request header into the given writer. 26 func EncodeRequestHeader(writer io.Writer, request *protocol.RequestHeader, requestAddons *Addons) error { 27 buffer := buf.StackNew() 28 defer buffer.Release() 29 30 if err := buffer.WriteByte(request.Version); err != nil { 31 return newError("failed to write request version").Base(err) 32 } 33 34 if _, err := buffer.Write(request.User.Account.(*vless.MemoryAccount).ID.Bytes()); err != nil { 35 return newError("failed to write request user id").Base(err) 36 } 37 38 if err := EncodeHeaderAddons(&buffer, requestAddons); err != nil { 39 return newError("failed to encode request header addons").Base(err) 40 } 41 42 if err := buffer.WriteByte(byte(request.Command)); err != nil { 43 return newError("failed to write request command").Base(err) 44 } 45 46 if request.Command != protocol.RequestCommandMux { 47 if err := addrParser.WriteAddressPort(&buffer, request.Address, request.Port); err != nil { 48 return newError("failed to write request address and port").Base(err) 49 } 50 } 51 52 if _, err := writer.Write(buffer.Bytes()); err != nil { 53 return newError("failed to write request header").Base(err) 54 } 55 56 return nil 57 } 58 59 // DecodeRequestHeader decodes and returns (if successful) a RequestHeader from an input stream. 60 func DecodeRequestHeader(isfb bool, first *buf.Buffer, reader io.Reader, validator *vless.Validator) (*protocol.RequestHeader, *Addons, bool, error) { 61 buffer := buf.StackNew() 62 defer buffer.Release() 63 64 request := new(protocol.RequestHeader) 65 66 if isfb { 67 request.Version = first.Byte(0) 68 } else { 69 if _, err := buffer.ReadFullFrom(reader, 1); err != nil { 70 return nil, nil, false, newError("failed to read request version").Base(err) 71 } 72 request.Version = buffer.Byte(0) 73 } 74 75 switch request.Version { 76 case 0: 77 78 var id [16]byte 79 80 if isfb { 81 copy(id[:], first.BytesRange(1, 17)) 82 } else { 83 buffer.Clear() 84 if _, err := buffer.ReadFullFrom(reader, 16); err != nil { 85 return nil, nil, false, newError("failed to read request user id").Base(err) 86 } 87 copy(id[:], buffer.Bytes()) 88 } 89 90 if request.User = validator.Get(id); request.User == nil { 91 return nil, nil, isfb, newError("invalid request user id") 92 } 93 94 if isfb { 95 first.Advance(17) 96 } 97 98 requestAddons, err := DecodeHeaderAddons(&buffer, reader) 99 if err != nil { 100 return nil, nil, false, newError("failed to decode request header addons").Base(err) 101 } 102 103 buffer.Clear() 104 if _, err := buffer.ReadFullFrom(reader, 1); err != nil { 105 return nil, nil, false, newError("failed to read request command").Base(err) 106 } 107 108 request.Command = protocol.RequestCommand(buffer.Byte(0)) 109 switch request.Command { 110 case protocol.RequestCommandMux: 111 request.Address = net.DomainAddress("v1.mux.cool") 112 request.Port = 0 113 case protocol.RequestCommandTCP, protocol.RequestCommandUDP: 114 if addr, port, err := addrParser.ReadAddressPort(&buffer, reader); err == nil { 115 request.Address = addr 116 request.Port = port 117 } 118 } 119 if request.Address == nil { 120 return nil, nil, false, newError("invalid request address") 121 } 122 return request, requestAddons, false, nil 123 default: 124 return nil, nil, isfb, newError("invalid request version") 125 } 126 } 127 128 // EncodeResponseHeader writes encoded response header into the given writer. 129 func EncodeResponseHeader(writer io.Writer, request *protocol.RequestHeader, responseAddons *Addons) error { 130 buffer := buf.StackNew() 131 defer buffer.Release() 132 133 if err := buffer.WriteByte(request.Version); err != nil { 134 return newError("failed to write response version").Base(err) 135 } 136 137 if err := EncodeHeaderAddons(&buffer, responseAddons); err != nil { 138 return newError("failed to encode response header addons").Base(err) 139 } 140 141 if _, err := writer.Write(buffer.Bytes()); err != nil { 142 return newError("failed to write response header").Base(err) 143 } 144 145 return nil 146 } 147 148 // DecodeResponseHeader decodes and returns (if successful) a ResponseHeader from an input stream. 149 func DecodeResponseHeader(reader io.Reader, request *protocol.RequestHeader) (*Addons, error) { 150 buffer := buf.StackNew() 151 defer buffer.Release() 152 153 if _, err := buffer.ReadFullFrom(reader, 1); err != nil { 154 return nil, newError("failed to read response version").Base(err) 155 } 156 157 if buffer.Byte(0) != request.Version { 158 return nil, newError("unexpected response version. Expecting ", int(request.Version), " but actually ", int(buffer.Byte(0))) 159 } 160 161 responseAddons, err := DecodeHeaderAddons(&buffer, reader) 162 if err != nil { 163 return nil, newError("failed to decode response header addons").Base(err) 164 } 165 166 return responseAddons, nil 167 }