github.com/moqsien/xraycore@v1.8.5/proxy/vless/encoding/encoding.go (about)

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