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