github.com/v2fly/v2ray-core/v5@v5.16.2-0.20240507031116-8191faa6e095/proxy/vless/encoding/encoding.go (about)

     1  package encoding
     2  
     3  //go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen
     4  
     5  import (
     6  	"io"
     7  
     8  	"github.com/v2fly/v2ray-core/v5/common/buf"
     9  	"github.com/v2fly/v2ray-core/v5/common/net"
    10  	"github.com/v2fly/v2ray-core/v5/common/protocol"
    11  	"github.com/v2fly/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  }