mihomo/transport/vless/vision.go

85 lines
2.3 KiB
Go
Raw Normal View History

2023-02-25 13:12:19 +08:00
package vless
import (
"bytes"
"encoding/binary"
2023-03-07 15:52:50 +08:00
"sync"
2023-02-25 13:12:19 +08:00
"github.com/Dreamacro/clash/common/buf"
"github.com/Dreamacro/clash/log"
"github.com/gofrs/uuid"
"github.com/zhangyunhao116/fastrand"
2023-02-25 13:12:19 +08:00
)
const (
paddingHeaderLen = 1 + 2 + 2 // =5
commandPaddingContinue byte = 0x00
commandPaddingEnd byte = 0x01
commandPaddingDirect byte = 0x02
)
2023-03-07 15:52:50 +08:00
var mutex sync.RWMutex
2023-03-04 21:47:06 +08:00
func WriteWithPadding(buffer *buf.Buffer, p []byte, command byte, userUUID *uuid.UUID, paddingTLS bool) {
2023-02-25 13:12:19 +08:00
contentLen := int32(len(p))
2023-03-07 15:52:50 +08:00
mutex.Lock()
2023-02-25 13:12:19 +08:00
var paddingLen int32
2023-03-04 21:47:06 +08:00
if contentLen < 900 && paddingTLS {
2023-03-07 15:52:50 +08:00
//log.Debugln("long padding")
paddingLen = fastrand.Int31n(500) + 900 - contentLen
2023-03-04 21:47:06 +08:00
} else {
paddingLen = fastrand.Int31n(256)
2023-03-04 21:47:06 +08:00
}
2023-03-07 15:52:50 +08:00
mutex.Unlock()
2023-02-25 13:12:19 +08:00
if userUUID != nil { // unnecessary, but keep the same with Xray
buffer.Write(userUUID.Bytes())
}
2023-03-04 21:47:06 +08:00
2023-02-25 13:12:19 +08:00
buffer.WriteByte(command)
binary.BigEndian.PutUint16(buffer.Extend(2), uint16(contentLen))
binary.BigEndian.PutUint16(buffer.Extend(2), uint16(paddingLen))
buffer.Write(p)
2023-03-07 15:52:50 +08:00
2023-02-25 13:12:19 +08:00
buffer.Extend(int(paddingLen))
log.Debugln("XTLS Vision write padding1: command=%v, payloadLen=%v, paddingLen=%v", command, contentLen, paddingLen)
}
2023-03-04 21:47:06 +08:00
func ApplyPadding(buffer *buf.Buffer, command byte, userUUID *uuid.UUID, paddingTLS bool) {
2023-02-25 13:12:19 +08:00
contentLen := int32(buffer.Len())
2023-03-07 15:52:50 +08:00
mutex.Lock()
2023-02-25 13:12:19 +08:00
var paddingLen int32
2023-03-04 21:47:06 +08:00
if contentLen < 900 && paddingTLS {
2023-03-07 15:52:50 +08:00
//log.Debugln("long padding")
paddingLen = fastrand.Int31n(500) + 900 - contentLen
2023-03-04 21:47:06 +08:00
} else {
paddingLen = fastrand.Int31n(256)
2023-03-04 21:47:06 +08:00
}
2023-03-07 15:52:50 +08:00
mutex.Unlock()
2023-02-25 13:12:19 +08:00
binary.BigEndian.PutUint16(buffer.ExtendHeader(2), uint16(paddingLen))
binary.BigEndian.PutUint16(buffer.ExtendHeader(2), uint16(contentLen))
buffer.ExtendHeader(1)[0] = command
if userUUID != nil { // unnecessary, but keep the same with Xray
copy(buffer.ExtendHeader(uuid.Size), userUUID.Bytes())
}
2023-03-07 15:52:50 +08:00
2023-02-25 13:12:19 +08:00
buffer.Extend(int(paddingLen))
log.Debugln("XTLS Vision write padding2: command=%d, payloadLen=%d, paddingLen=%d", command, contentLen, paddingLen)
}
func ReshapeBuffer(buffer *buf.Buffer) *buf.Buffer {
if buffer.Len() <= buf.BufferSize-paddingHeaderLen {
return nil
}
cutAt := bytes.LastIndex(buffer.Bytes(), tlsApplicationDataStart)
if cutAt == -1 {
cutAt = buf.BufferSize / 2
}
buffer2 := buf.New()
buffer2.Write(buffer.From(cutAt))
buffer.Truncate(cutAt)
return buffer2
}