github.com/metacubex/mihomo@v1.18.5/transport/vless/vision/padding.go (about)

     1  package vision
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/binary"
     6  
     7  	"github.com/metacubex/mihomo/common/buf"
     8  	"github.com/metacubex/mihomo/log"
     9  
    10  	"github.com/gofrs/uuid/v5"
    11  	"github.com/zhangyunhao116/fastrand"
    12  )
    13  
    14  const (
    15  	PaddingHeaderLen = uuid.Size + 1 + 2 + 2 // =21
    16  
    17  	commandPaddingContinue byte = 0x00
    18  	commandPaddingEnd      byte = 0x01
    19  	commandPaddingDirect   byte = 0x02
    20  )
    21  
    22  func WriteWithPadding(buffer *buf.Buffer, p []byte, command byte, userUUID *uuid.UUID, paddingTLS bool) {
    23  	contentLen := int32(len(p))
    24  	var paddingLen int32
    25  	if contentLen < 900 {
    26  		if paddingTLS {
    27  			//log.Debugln("long padding")
    28  			paddingLen = fastrand.Int31n(500) + 900 - contentLen
    29  		} else {
    30  			paddingLen = fastrand.Int31n(256)
    31  		}
    32  	}
    33  	if userUUID != nil {
    34  		buffer.Write(userUUID.Bytes())
    35  	}
    36  
    37  	buffer.WriteByte(command)
    38  	binary.BigEndian.PutUint16(buffer.Extend(2), uint16(contentLen))
    39  	binary.BigEndian.PutUint16(buffer.Extend(2), uint16(paddingLen))
    40  	buffer.Write(p)
    41  
    42  	buffer.Extend(int(paddingLen))
    43  	log.Debugln("XTLS Vision write padding1: command=%v, payloadLen=%v, paddingLen=%v", command, contentLen, paddingLen)
    44  }
    45  
    46  func ApplyPadding(buffer *buf.Buffer, command byte, userUUID *uuid.UUID, paddingTLS bool) {
    47  	contentLen := int32(buffer.Len())
    48  	var paddingLen int32
    49  	if contentLen < 900 {
    50  		if paddingTLS {
    51  			//log.Debugln("long padding")
    52  			paddingLen = fastrand.Int31n(500) + 900 - contentLen
    53  		} else {
    54  			paddingLen = fastrand.Int31n(256)
    55  		}
    56  	}
    57  
    58  	binary.BigEndian.PutUint16(buffer.ExtendHeader(2), uint16(paddingLen))
    59  	binary.BigEndian.PutUint16(buffer.ExtendHeader(2), uint16(contentLen))
    60  	buffer.ExtendHeader(1)[0] = command
    61  	if userUUID != nil {
    62  		copy(buffer.ExtendHeader(uuid.Size), userUUID.Bytes())
    63  	}
    64  
    65  	buffer.Extend(int(paddingLen))
    66  	log.Debugln("XTLS Vision write padding2: command=%d, payloadLen=%d, paddingLen=%d", command, contentLen, paddingLen)
    67  }
    68  
    69  func ReshapeBuffer(buffer *buf.Buffer) *buf.Buffer {
    70  	if buffer.Len() <= buf.BufferSize-PaddingHeaderLen {
    71  		return nil
    72  	}
    73  	cutAt := bytes.LastIndex(buffer.Bytes(), tlsApplicationDataStart)
    74  	if cutAt == -1 {
    75  		cutAt = buf.BufferSize / 2
    76  	}
    77  	buffer2 := buf.New()
    78  	buffer2.Write(buffer.From(cutAt))
    79  	buffer.Truncate(cutAt)
    80  	return buffer2
    81  }