github.com/v2fly/v2ray-core/v4@v4.45.2/proxy/vless/encoding/encoding.go (about)

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