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  }