github.com/xraypb/xray-core@v1.6.6/proxy/vless/encoding/encoding.go (about)

     1  package encoding
     2  
     3  //go:generate go run github.com/xraypb/xray-core/common/errors/errorgen
     4  
     5  import (
     6  	"bytes"
     7  	"context"
     8  	"crypto/rand"
     9  	"fmt"
    10  	"io"
    11  	"math/big"
    12  	"runtime"
    13  	"strconv"
    14  	"syscall"
    15  	"time"
    16  
    17  	"github.com/xraypb/xray-core/common/buf"
    18  	"github.com/xraypb/xray-core/common/errors"
    19  	"github.com/xraypb/xray-core/common/net"
    20  	"github.com/xraypb/xray-core/common/protocol"
    21  	"github.com/xraypb/xray-core/common/session"
    22  	"github.com/xraypb/xray-core/common/signal"
    23  	"github.com/xraypb/xray-core/features/stats"
    24  	"github.com/xraypb/xray-core/proxy/vless"
    25  	"github.com/xraypb/xray-core/transport/internet/stat"
    26  	"github.com/xraypb/xray-core/transport/internet/tls"
    27  	"github.com/xraypb/xray-core/transport/internet/xtls"
    28  )
    29  
    30  const (
    31  	Version = byte(0)
    32  )
    33  
    34  var tls13SupportedVersions = []byte{0x00, 0x2b, 0x00, 0x02, 0x03, 0x04}
    35  var tlsClientHandShakeStart = []byte{0x16, 0x03}
    36  var tlsServerHandShakeStart = []byte{0x16, 0x03, 0x03}
    37  var tlsApplicationDataStart = []byte{0x17, 0x03, 0x03}
    38  
    39  var addrParser = protocol.NewAddressParser(
    40  	protocol.AddressFamilyByte(byte(protocol.AddressTypeIPv4), net.AddressFamilyIPv4),
    41  	protocol.AddressFamilyByte(byte(protocol.AddressTypeDomain), net.AddressFamilyDomain),
    42  	protocol.AddressFamilyByte(byte(protocol.AddressTypeIPv6), net.AddressFamilyIPv6),
    43  	protocol.PortThenAddress(),
    44  )
    45  
    46  // EncodeRequestHeader writes encoded request header into the given writer.
    47  func EncodeRequestHeader(writer io.Writer, request *protocol.RequestHeader, requestAddons *Addons) error {
    48  	buffer := buf.StackNew()
    49  	defer buffer.Release()
    50  
    51  	if err := buffer.WriteByte(request.Version); err != nil {
    52  		return newError("failed to write request version").Base(err)
    53  	}
    54  
    55  	if _, err := buffer.Write(request.User.Account.(*vless.MemoryAccount).ID.Bytes()); err != nil {
    56  		return newError("failed to write request user id").Base(err)
    57  	}
    58  
    59  	if err := EncodeHeaderAddons(&buffer, requestAddons); err != nil {
    60  		return newError("failed to encode request header addons").Base(err)
    61  	}
    62  
    63  	if err := buffer.WriteByte(byte(request.Command)); err != nil {
    64  		return newError("failed to write request command").Base(err)
    65  	}
    66  
    67  	if request.Command != protocol.RequestCommandMux {
    68  		if err := addrParser.WriteAddressPort(&buffer, request.Address, request.Port); err != nil {
    69  			return newError("failed to write request address and port").Base(err)
    70  		}
    71  	}
    72  
    73  	if _, err := writer.Write(buffer.Bytes()); err != nil {
    74  		return newError("failed to write request header").Base(err)
    75  	}
    76  
    77  	return nil
    78  }
    79  
    80  // DecodeRequestHeader decodes and returns (if successful) a RequestHeader from an input stream.
    81  func DecodeRequestHeader(isfb bool, first *buf.Buffer, reader io.Reader, validator *vless.Validator) (*protocol.RequestHeader, *Addons, bool, error) {
    82  	buffer := buf.StackNew()
    83  	defer buffer.Release()
    84  
    85  	request := new(protocol.RequestHeader)
    86  
    87  	if isfb {
    88  		request.Version = first.Byte(0)
    89  	} else {
    90  		if _, err := buffer.ReadFullFrom(reader, 1); err != nil {
    91  			return nil, nil, false, newError("failed to read request version").Base(err)
    92  		}
    93  		request.Version = buffer.Byte(0)
    94  	}
    95  
    96  	switch request.Version {
    97  	case 0:
    98  
    99  		var id [16]byte
   100  
   101  		if isfb {
   102  			copy(id[:], first.BytesRange(1, 17))
   103  		} else {
   104  			buffer.Clear()
   105  			if _, err := buffer.ReadFullFrom(reader, 16); err != nil {
   106  				return nil, nil, false, newError("failed to read request user id").Base(err)
   107  			}
   108  			copy(id[:], buffer.Bytes())
   109  		}
   110  
   111  		if request.User = validator.Get(id); request.User == nil {
   112  			return nil, nil, isfb, newError("invalid request user id")
   113  		}
   114  
   115  		if isfb {
   116  			first.Advance(17)
   117  		}
   118  
   119  		requestAddons, err := DecodeHeaderAddons(&buffer, reader)
   120  		if err != nil {
   121  			return nil, nil, false, newError("failed to decode request header addons").Base(err)
   122  		}
   123  
   124  		buffer.Clear()
   125  		if _, err := buffer.ReadFullFrom(reader, 1); err != nil {
   126  			return nil, nil, false, newError("failed to read request command").Base(err)
   127  		}
   128  
   129  		request.Command = protocol.RequestCommand(buffer.Byte(0))
   130  		switch request.Command {
   131  		case protocol.RequestCommandMux:
   132  			request.Address = net.DomainAddress("v1.mux.cool")
   133  			request.Port = 0
   134  		case protocol.RequestCommandTCP, protocol.RequestCommandUDP:
   135  			if addr, port, err := addrParser.ReadAddressPort(&buffer, reader); err == nil {
   136  				request.Address = addr
   137  				request.Port = port
   138  			}
   139  		}
   140  		if request.Address == nil {
   141  			return nil, nil, false, newError("invalid request address")
   142  		}
   143  		return request, requestAddons, false, nil
   144  	default:
   145  		return nil, nil, isfb, newError("invalid request version")
   146  	}
   147  }
   148  
   149  // EncodeResponseHeader writes encoded response header into the given writer.
   150  func EncodeResponseHeader(writer io.Writer, request *protocol.RequestHeader, responseAddons *Addons) error {
   151  	buffer := buf.StackNew()
   152  	defer buffer.Release()
   153  
   154  	if err := buffer.WriteByte(request.Version); err != nil {
   155  		return newError("failed to write response version").Base(err)
   156  	}
   157  
   158  	if err := EncodeHeaderAddons(&buffer, responseAddons); err != nil {
   159  		return newError("failed to encode response header addons").Base(err)
   160  	}
   161  
   162  	if _, err := writer.Write(buffer.Bytes()); err != nil {
   163  		return newError("failed to write response header").Base(err)
   164  	}
   165  
   166  	return nil
   167  }
   168  
   169  // DecodeResponseHeader decodes and returns (if successful) a ResponseHeader from an input stream.
   170  func DecodeResponseHeader(reader io.Reader, request *protocol.RequestHeader) (*Addons, error) {
   171  	buffer := buf.StackNew()
   172  	defer buffer.Release()
   173  
   174  	if _, err := buffer.ReadFullFrom(reader, 1); err != nil {
   175  		return nil, newError("failed to read response version").Base(err)
   176  	}
   177  
   178  	if buffer.Byte(0) != request.Version {
   179  		return nil, newError("unexpected response version. Expecting ", int(request.Version), " but actually ", int(buffer.Byte(0)))
   180  	}
   181  
   182  	responseAddons, err := DecodeHeaderAddons(&buffer, reader)
   183  	if err != nil {
   184  		return nil, newError("failed to decode response header addons").Base(err)
   185  	}
   186  
   187  	return responseAddons, nil
   188  }
   189  
   190  func ReadV(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater, conn *xtls.Conn, rawConn syscall.RawConn, counter stats.Counter, ctx context.Context) error {
   191  	err := func() error {
   192  		var ct stats.Counter
   193  		for {
   194  			if conn.DirectIn {
   195  				conn.DirectIn = false
   196  				if inbound := session.InboundFromContext(ctx); inbound != nil && inbound.Conn != nil {
   197  					iConn := inbound.Conn
   198  					statConn, ok := iConn.(*stat.CounterConnection)
   199  					if ok {
   200  						iConn = statConn.Connection
   201  					}
   202  					if xc, ok := iConn.(*xtls.Conn); ok {
   203  						iConn = xc.NetConn()
   204  					}
   205  					if tc, ok := iConn.(*net.TCPConn); ok {
   206  						if conn.SHOW {
   207  							fmt.Println(conn.MARK, "Splice")
   208  						}
   209  						runtime.Gosched() // necessary
   210  						w, err := tc.ReadFrom(conn.NetConn())
   211  						if counter != nil {
   212  							counter.Add(w)
   213  						}
   214  						if statConn != nil && statConn.WriteCounter != nil {
   215  							statConn.WriteCounter.Add(w)
   216  						}
   217  						return err
   218  					} else {
   219  						panic("XTLS Splice: not TCP inbound")
   220  					}
   221  				}
   222  				reader = buf.NewReadVReader(conn.NetConn(), rawConn, nil)
   223  				ct = counter
   224  				if conn.SHOW {
   225  					fmt.Println(conn.MARK, "ReadV")
   226  				}
   227  			}
   228  			buffer, err := reader.ReadMultiBuffer()
   229  			if !buffer.IsEmpty() {
   230  				if ct != nil {
   231  					ct.Add(int64(buffer.Len()))
   232  				}
   233  				timer.Update()
   234  				if werr := writer.WriteMultiBuffer(buffer); werr != nil {
   235  					return werr
   236  				}
   237  			}
   238  			if err != nil {
   239  				return err
   240  			}
   241  		}
   242  	}()
   243  	if err != nil && errors.Cause(err) != io.EOF {
   244  		return err
   245  	}
   246  	return nil
   247  }
   248  
   249  // XtlsRead filter and read xtls protocol
   250  func XtlsRead(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater, conn net.Conn, rawConn syscall.RawConn,
   251  	counter stats.Counter, ctx context.Context, userUUID []byte, numberOfPacketToFilter *int, enableXtls *bool,
   252  	isTLS12orAbove *bool, isTLS *bool, cipher *uint16, remainingServerHello *int32) error {
   253  	err := func() error {
   254  		var ct stats.Counter
   255  		filterUUID := true
   256  		shouldSwitchToDirectCopy := false
   257  		var remainingContent int32 = -1
   258  		var remainingPadding int32 = -1
   259  		currentCommand := 0
   260  		for {
   261  			if shouldSwitchToDirectCopy {
   262  				shouldSwitchToDirectCopy = false
   263  				if runtime.GOOS == "linux" || runtime.GOOS == "android" {
   264  					if inbound := session.InboundFromContext(ctx); inbound != nil && inbound.Conn != nil {
   265  						iConn := inbound.Conn
   266  						statConn, ok := iConn.(*stat.CounterConnection)
   267  						if ok {
   268  							iConn = statConn.Connection
   269  						}
   270  						if xc, ok := iConn.(*tls.Conn); ok {
   271  							iConn = xc.NetConn()
   272  						}
   273  						if tc, ok := iConn.(*net.TCPConn); ok {
   274  							newError("XtlsRead splice").WriteToLog(session.ExportIDToError(ctx))
   275  							runtime.Gosched() // necessary
   276  							w, err := tc.ReadFrom(conn)
   277  							if counter != nil {
   278  								counter.Add(w)
   279  							}
   280  							if statConn != nil && statConn.WriteCounter != nil {
   281  								statConn.WriteCounter.Add(w)
   282  							}
   283  							return err
   284  						} else {
   285  							panic("XTLS Splice: not TCP inbound")
   286  						}
   287  					} else {
   288  						// panic("XTLS Splice: nil inbound or nil inbound.Conn")
   289  					}
   290  				}
   291  				reader = buf.NewReadVReader(conn, rawConn, nil)
   292  				ct = counter
   293  				newError("XtlsRead readV").WriteToLog(session.ExportIDToError(ctx))
   294  			}
   295  			buffer, err := reader.ReadMultiBuffer()
   296  			if !buffer.IsEmpty() {
   297  				if filterUUID && (*isTLS || *numberOfPacketToFilter > 0) {
   298  					buffer = XtlsUnpadding(ctx, buffer, userUUID, &remainingContent, &remainingPadding, &currentCommand)
   299  					if remainingContent == 0 && remainingPadding == 0 {
   300  						if currentCommand == 1 {
   301  							filterUUID = false
   302  						} else if currentCommand == 2 {
   303  							filterUUID = false
   304  							shouldSwitchToDirectCopy = true
   305  						} else if currentCommand != 0 {
   306  							newError("XtlsRead unknown command ", currentCommand, buffer.Len()).WriteToLog(session.ExportIDToError(ctx))
   307  						}
   308  					}
   309  				}
   310  				if *numberOfPacketToFilter > 0 {
   311  					XtlsFilterTls(buffer, numberOfPacketToFilter, enableXtls, isTLS12orAbove, isTLS, cipher, remainingServerHello, ctx)
   312  				}
   313  				if ct != nil {
   314  					ct.Add(int64(buffer.Len()))
   315  				}
   316  				timer.Update()
   317  				if werr := writer.WriteMultiBuffer(buffer); werr != nil {
   318  					return werr
   319  				}
   320  			}
   321  			if err != nil {
   322  				return err
   323  			}
   324  		}
   325  	}()
   326  	if err != nil && errors.Cause(err) != io.EOF {
   327  		return err
   328  	}
   329  	return nil
   330  }
   331  
   332  // XtlsWrite filter and write xtls protocol
   333  func XtlsWrite(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater, conn net.Conn, counter stats.Counter,
   334  	ctx context.Context, userUUID *[]byte, numberOfPacketToFilter *int, enableXtls *bool, isTLS12orAbove *bool, isTLS *bool,
   335  	cipher *uint16, remainingServerHello *int32) error {
   336  	err := func() error {
   337  		var ct stats.Counter
   338  		filterTlsApplicationData := true
   339  		shouldSwitchToDirectCopy := false
   340  		for {
   341  			buffer, err := reader.ReadMultiBuffer()
   342  			if !buffer.IsEmpty() {
   343  				if *numberOfPacketToFilter > 0 {
   344  					XtlsFilterTls(buffer, numberOfPacketToFilter, enableXtls, isTLS12orAbove, isTLS, cipher, remainingServerHello, ctx)
   345  				}
   346  				if filterTlsApplicationData && *isTLS {
   347  					buffer = ReshapeMultiBuffer(ctx, buffer)
   348  					var xtlsSpecIndex int
   349  					for i, b := range buffer {
   350  						if b.Len() >= 6 && bytes.Equal(tlsApplicationDataStart, b.BytesTo(3)) {
   351  							var command byte = 0x01
   352  							if *enableXtls {
   353  								shouldSwitchToDirectCopy = true
   354  								xtlsSpecIndex = i
   355  								command = 0x02
   356  							}
   357  							filterTlsApplicationData = false
   358  							buffer[i] = XtlsPadding(b, command, userUUID, ctx)
   359  							break
   360  						} else if !*isTLS12orAbove && *numberOfPacketToFilter <= 0 {
   361  							//maybe tls 1.1 or 1.0
   362  							filterTlsApplicationData = false
   363  							buffer[i] = XtlsPadding(b, 0x01, userUUID, ctx)
   364  							break
   365  						}
   366  						buffer[i] = XtlsPadding(b, 0x00, userUUID, ctx)
   367  					}
   368  					if shouldSwitchToDirectCopy {
   369  						encryptBuffer, directBuffer := buf.SplitMulti(buffer, xtlsSpecIndex+1)
   370  						length := encryptBuffer.Len()
   371  						if !encryptBuffer.IsEmpty() {
   372  							timer.Update()
   373  							if werr := writer.WriteMultiBuffer(encryptBuffer); werr != nil {
   374  								return werr
   375  							}
   376  						}
   377  						buffer = directBuffer
   378  						writer = buf.NewWriter(conn)
   379  						ct = counter
   380  						newError("XtlsWrite writeV ", xtlsSpecIndex, " ", length, " ", buffer.Len()).WriteToLog(session.ExportIDToError(ctx))
   381  						time.Sleep(5 * time.Millisecond) // for some device, the first xtls direct packet fails without this delay
   382  					}
   383  				}
   384  				if !buffer.IsEmpty() {
   385  					if ct != nil {
   386  						ct.Add(int64(buffer.Len()))
   387  					}
   388  					timer.Update()
   389  					if werr := writer.WriteMultiBuffer(buffer); werr != nil {
   390  						return werr
   391  					}
   392  				}
   393  			}
   394  			if err != nil {
   395  				return err
   396  			}
   397  		}
   398  	}()
   399  	if err != nil && errors.Cause(err) != io.EOF {
   400  		return err
   401  	}
   402  	return nil
   403  }
   404  
   405  // XtlsFilterTls filter and recognize tls 1.3 and other info
   406  func XtlsFilterTls(buffer buf.MultiBuffer, numberOfPacketToFilter *int, enableXtls *bool, isTLS12orAbove *bool, isTLS *bool,
   407  	cipher *uint16, remainingServerHello *int32, ctx context.Context) {
   408  	for _, b := range buffer {
   409  		*numberOfPacketToFilter--
   410  		if b.Len() >= 6 {
   411  			startsBytes := b.BytesTo(6)
   412  			if bytes.Equal(tlsServerHandShakeStart, startsBytes[:3]) && startsBytes[5] == 0x02 {
   413  				*remainingServerHello = (int32(startsBytes[3])<<8 | int32(startsBytes[4])) + 5
   414  				*isTLS12orAbove = true
   415  				*isTLS = true
   416  				if b.Len() >= 79 && *remainingServerHello >= 79 {
   417  					sessionIdLen := int32(b.Byte(43))
   418  					cipherSuite := b.BytesRange(43+sessionIdLen+1, 43+sessionIdLen+3)
   419  					*cipher = uint16(cipherSuite[0])<<8 | uint16(cipherSuite[1])
   420  				} else {
   421  					newError("XtlsFilterTls short server hello, tls 1.2 or older? ", b.Len(), " ", *remainingServerHello).WriteToLog(session.ExportIDToError(ctx))
   422  				}
   423  			} else if bytes.Equal(tlsClientHandShakeStart, startsBytes[:2]) && startsBytes[5] == 0x01 {
   424  				*isTLS = true
   425  				newError("XtlsFilterTls found tls client hello! ", buffer.Len()).WriteToLog(session.ExportIDToError(ctx))
   426  			}
   427  		}
   428  		if *remainingServerHello > 0 {
   429  			end := *remainingServerHello
   430  			if end > b.Len() {
   431  				end = b.Len()
   432  			}
   433  			*remainingServerHello -= b.Len()
   434  			if bytes.Contains(b.BytesTo(end), tls13SupportedVersions) {
   435  				v, ok := Tls13CipherSuiteDic[*cipher]
   436  				if !ok {
   437  					v = "Old cipher: " + strconv.FormatUint(uint64(*cipher), 16)
   438  				} else if v != "TLS_AES_128_CCM_8_SHA256" {
   439  					*enableXtls = true
   440  				}
   441  				newError("XtlsFilterTls found tls 1.3! ", b.Len(), " ", v).WriteToLog(session.ExportIDToError(ctx))
   442  				*numberOfPacketToFilter = 0
   443  				return
   444  			} else if *remainingServerHello <= 0 {
   445  				newError("XtlsFilterTls found tls 1.2! ", b.Len()).WriteToLog(session.ExportIDToError(ctx))
   446  				*numberOfPacketToFilter = 0
   447  				return
   448  			}
   449  			newError("XtlsFilterTls inclusive server hello ", b.Len(), " ", *remainingServerHello).WriteToLog(session.ExportIDToError(ctx))
   450  		}
   451  		if *numberOfPacketToFilter <= 0 {
   452  			newError("XtlsFilterTls stop filtering", buffer.Len()).WriteToLog(session.ExportIDToError(ctx))
   453  		}
   454  	}
   455  }
   456  
   457  // ReshapeMultiBuffer prepare multi buffer for padding stucture (max 21 bytes)
   458  func ReshapeMultiBuffer(ctx context.Context, buffer buf.MultiBuffer) buf.MultiBuffer {
   459  	needReshape := false
   460  	for _, b := range buffer {
   461  		if b.Len() >= buf.Size-21 {
   462  			needReshape = true
   463  		}
   464  	}
   465  	if !needReshape {
   466  		return buffer
   467  	}
   468  	mb2 := make(buf.MultiBuffer, 0, len(buffer))
   469  	print := ""
   470  	for _, b := range buffer {
   471  		if b.Len() >= buf.Size-21 {
   472  			index := int32(bytes.LastIndex(b.Bytes(), tlsApplicationDataStart))
   473  			if index <= 0 {
   474  				index = buf.Size / 2
   475  			}
   476  			buffer1 := buf.New()
   477  			buffer2 := buf.New()
   478  			buffer1.Write(b.BytesTo(index))
   479  			buffer2.Write(b.BytesFrom(index))
   480  			mb2 = append(mb2, buffer1, buffer2)
   481  			print += " " + strconv.Itoa(int(buffer1.Len())) + " " + strconv.Itoa(int(buffer2.Len()))
   482  		} else {
   483  			newbuffer := buf.New()
   484  			newbuffer.Write(b.Bytes())
   485  			mb2 = append(mb2, newbuffer)
   486  			print += " " + strconv.Itoa(int(b.Len()))
   487  		}
   488  	}
   489  	buf.ReleaseMulti(buffer)
   490  	newError("ReshapeMultiBuffer ", print).WriteToLog(session.ExportIDToError(ctx))
   491  	return mb2
   492  }
   493  
   494  // XtlsPadding add padding to eliminate length siganature during tls handshake
   495  func XtlsPadding(b *buf.Buffer, command byte, userUUID *[]byte, ctx context.Context) *buf.Buffer {
   496  	var length int32 = 0
   497  	if b.Len() < 900 {
   498  		l, err := rand.Int(rand.Reader, big.NewInt(500))
   499  		if err != nil {
   500  			newError("failed to generate padding").Base(err).WriteToLog(session.ExportIDToError(ctx))
   501  		}
   502  		length = int32(l.Int64()) + 900 - b.Len()
   503  	}
   504  	newbuffer := buf.New()
   505  	if userUUID != nil {
   506  		newbuffer.Write(*userUUID)
   507  		*userUUID = nil
   508  	}
   509  	newbuffer.Write([]byte{command, byte(b.Len() >> 8), byte(b.Len()), byte(length >> 8), byte(length)})
   510  	newbuffer.Write(b.Bytes())
   511  	newbuffer.Extend(length)
   512  	newError("XtlsPadding ", b.Len(), " ", length, " ", command).WriteToLog(session.ExportIDToError(ctx))
   513  	b.Release()
   514  	b = nil
   515  	return newbuffer
   516  }
   517  
   518  // XtlsUnpadding remove padding and parse command
   519  func XtlsUnpadding(ctx context.Context, buffer buf.MultiBuffer, userUUID []byte, remainingContent *int32, remainingPadding *int32, currentCommand *int) buf.MultiBuffer {
   520  	posindex := 0
   521  	var posByte int32 = 0
   522  	if *remainingContent == -1 && *remainingPadding == -1 {
   523  		for i, b := range buffer {
   524  			if b.Len() >= 21 && bytes.Equal(userUUID, b.BytesTo(16)) {
   525  				posindex = i
   526  				posByte = 16
   527  				*remainingContent = 0
   528  				*remainingPadding = 0
   529  				break
   530  			}
   531  		}
   532  	}
   533  	if *remainingContent == -1 && *remainingPadding == -1 {
   534  		return buffer
   535  	}
   536  	mb2 := make(buf.MultiBuffer, 0, len(buffer))
   537  	for i := 0; i < posindex; i++ {
   538  		newbuffer := buf.New()
   539  		newbuffer.Write(buffer[i].Bytes())
   540  		mb2 = append(mb2, newbuffer)
   541  	}
   542  	for i := posindex; i < len(buffer); i++ {
   543  		b := buffer[i]
   544  		for posByte < b.Len() {
   545  			if *remainingContent <= 0 && *remainingPadding <= 0 {
   546  				if *currentCommand == 1 { // possible buffer after padding, no need to worry about xtls (command 2)
   547  					len := b.Len() - posByte
   548  					newbuffer := buf.New()
   549  					newbuffer.Write(b.BytesRange(posByte, posByte+len))
   550  					mb2 = append(mb2, newbuffer)
   551  					posByte += len
   552  				} else {
   553  					paddingInfo := b.BytesRange(posByte, posByte+5)
   554  					*currentCommand = int(paddingInfo[0])
   555  					*remainingContent = int32(paddingInfo[1])<<8 | int32(paddingInfo[2])
   556  					*remainingPadding = int32(paddingInfo[3])<<8 | int32(paddingInfo[4])
   557  					newError("Xtls Unpadding new block", i, " ", posByte, " content ", *remainingContent, " padding ", *remainingPadding, " ", paddingInfo[0]).WriteToLog(session.ExportIDToError(ctx))
   558  					posByte += 5
   559  				}
   560  			} else if *remainingContent > 0 {
   561  				len := *remainingContent
   562  				if b.Len() < posByte+*remainingContent {
   563  					len = b.Len() - posByte
   564  				}
   565  				newbuffer := buf.New()
   566  				newbuffer.Write(b.BytesRange(posByte, posByte+len))
   567  				mb2 = append(mb2, newbuffer)
   568  				*remainingContent -= len
   569  				posByte += len
   570  			} else { // remainingPadding > 0
   571  				len := *remainingPadding
   572  				if b.Len() < posByte+*remainingPadding {
   573  					len = b.Len() - posByte
   574  				}
   575  				*remainingPadding -= len
   576  				posByte += len
   577  			}
   578  			if posByte == b.Len() {
   579  				posByte = 0
   580  				break
   581  			}
   582  		}
   583  	}
   584  	buf.ReleaseMulti(buffer)
   585  	return mb2
   586  }
   587  
   588  var Tls13CipherSuiteDic = map[uint16]string{
   589  	0x1301: "TLS_AES_128_GCM_SHA256",
   590  	0x1302: "TLS_AES_256_GCM_SHA384",
   591  	0x1303: "TLS_CHACHA20_POLY1305_SHA256",
   592  	0x1304: "TLS_AES_128_CCM_SHA256",
   593  	0x1305: "TLS_AES_128_CCM_8_SHA256",
   594  }