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 }