chore: rewrite vision client write

This commit is contained in:
wwqgtxx 2025-08-22 11:27:32 +08:00
parent 48f3ea8bc9
commit cdf5e0c73e
4 changed files with 40 additions and 51 deletions

View File

@ -14,6 +14,7 @@ var NewPacket = buf.NewPacket
var NewSize = buf.NewSize var NewSize = buf.NewSize
var With = buf.With var With = buf.With
var As = buf.As var As = buf.As
var ReleaseMulti = buf.ReleaseMulti
var ( var (
Must = common.Must Must = common.Must

View File

@ -22,6 +22,10 @@ type ExtendedReader = network.ExtendedReader
var WriteBuffer = bufio.WriteBuffer var WriteBuffer = bufio.WriteBuffer
type ReadWaitOptions = network.ReadWaitOptions
var NewReadWaitOptions = network.NewReadWaitOptions
func NewDeadlineConn(conn net.Conn) ExtendedConn { func NewDeadlineConn(conn net.Conn) ExtendedConn {
if deadline.IsPipe(conn) || deadline.IsPipe(network.UnwrapReader(conn)) { if deadline.IsPipe(conn) || deadline.IsPipe(network.UnwrapReader(conn)) {
return NewExtendedConn(conn) // pipe always have correctly deadline implement return NewExtendedConn(conn) // pipe always have correctly deadline implement

View File

@ -170,7 +170,7 @@ func (vc *Conn) WriteBuffer(buffer *buf.Buffer) (err error) {
if vc.needHandshake { if vc.needHandshake {
vc.needHandshake = false vc.needHandshake = false
if buffer.IsEmpty() { if buffer.IsEmpty() {
ApplyPadding(buffer, commandPaddingContinue, vc.userUUID, false) ApplyPadding(buffer, commandPaddingContinue, vc.userUUID, true) // we do a long padding to hide vless header
} else { } else {
vc.FilterTLS(buffer.Bytes()) vc.FilterTLS(buffer.Bytes())
ApplyPadding(buffer, commandPaddingContinue, vc.userUUID, vc.isTLS) ApplyPadding(buffer, commandPaddingContinue, vc.userUUID, vc.isTLS)
@ -190,55 +190,37 @@ func (vc *Conn) WriteBuffer(buffer *buf.Buffer) (err error) {
} }
if vc.writeFilterApplicationData { if vc.writeFilterApplicationData {
buffer2 := ReshapeBuffer(buffer)
defer buffer2.Release()
vc.FilterTLS(buffer.Bytes()) vc.FilterTLS(buffer.Bytes())
command := commandPaddingContinue buffers := vc.ReshapeBuffer(buffer)
if !vc.isTLS { applyPadding := true
command = commandPaddingEnd for i, buffer := range buffers {
command := commandPaddingContinue
// disable XTLS if applyPadding {
//vc.readProcess = false if vc.isTLS && buffer.Len() > 6 && bytes.Equal(buffer.To(3), tlsApplicationDataStart) {
vc.writeFilterApplicationData = false command = commandPaddingEnd
vc.packetsToFilter = 0 if vc.enableXTLS {
} else if buffer.Len() > 6 && bytes.Equal(buffer.To(3), tlsApplicationDataStart) || vc.packetsToFilter <= 0 { command = commandPaddingDirect
command = commandPaddingEnd vc.writeDirect = true
if vc.enableXTLS { }
command = commandPaddingDirect vc.writeFilterApplicationData = false
vc.writeDirect = true applyPadding = false
} } else if !vc.isTLS12orAbove && vc.packetsToFilter <= 1 {
vc.writeFilterApplicationData = false command = commandPaddingEnd
} vc.writeFilterApplicationData = false
ApplyPadding(buffer, command, nil, vc.isTLS) applyPadding = false
err = vc.ExtendedWriter.WriteBuffer(buffer)
if err != nil {
return err
}
if vc.writeDirect {
vc.ExtendedWriter = N.NewExtendedWriter(vc.netConn)
log.Debugln("XTLS Vision direct write start")
//time.Sleep(5 * time.Millisecond)
}
if buffer2 != nil {
if vc.writeDirect || !vc.isTLS {
return vc.ExtendedWriter.WriteBuffer(buffer2)
}
vc.FilterTLS(buffer2.Bytes())
command = commandPaddingContinue
if buffer2.Len() > 6 && bytes.Equal(buffer2.To(3), tlsApplicationDataStart) || vc.packetsToFilter <= 0 {
command = commandPaddingEnd
if vc.enableXTLS {
command = commandPaddingDirect
vc.writeDirect = true
} }
vc.writeFilterApplicationData = false ApplyPadding(buffer, command, nil, vc.isTLS)
} }
ApplyPadding(buffer2, command, nil, vc.isTLS)
err = vc.ExtendedWriter.WriteBuffer(buffer2) err = vc.ExtendedWriter.WriteBuffer(buffer)
if vc.writeDirect { if err != nil {
buf.ReleaseMulti(buffers[i:]) // release unwritten buffers
return
}
if command == commandPaddingDirect {
vc.ExtendedWriter = N.NewExtendedWriter(vc.netConn) vc.ExtendedWriter = N.NewExtendedWriter(vc.netConn)
log.Debugln("XTLS Vision direct write start") log.Debugln("XTLS Vision direct write start")
//time.Sleep(10 * time.Millisecond) //time.Sleep(5 * time.Millisecond)
} }
} }
return err return err

View File

@ -6,6 +6,7 @@ import (
"github.com/metacubex/mihomo/common/buf" "github.com/metacubex/mihomo/common/buf"
"github.com/metacubex/mihomo/log" "github.com/metacubex/mihomo/log"
N "github.com/metacubex/sing/common/network"
"github.com/gofrs/uuid/v5" "github.com/gofrs/uuid/v5"
"github.com/metacubex/randv2" "github.com/metacubex/randv2"
@ -42,16 +43,17 @@ func ApplyPadding(buffer *buf.Buffer, command byte, userUUID *uuid.UUID, padding
log.Debugln("XTLS Vision write padding: command=%d, payloadLen=%d, paddingLen=%d", command, contentLen, paddingLen) log.Debugln("XTLS Vision write padding: command=%d, payloadLen=%d, paddingLen=%d", command, contentLen, paddingLen)
} }
func ReshapeBuffer(buffer *buf.Buffer) *buf.Buffer { func (vc *Conn) ReshapeBuffer(buffer *buf.Buffer) []*buf.Buffer {
if buffer.Len() <= buf.BufferSize-PaddingHeaderLen { const xrayBufSize = 8192
return nil if buffer.Len() <= xrayBufSize-PaddingHeaderLen {
return []*buf.Buffer{buffer}
} }
cutAt := bytes.LastIndex(buffer.Bytes(), tlsApplicationDataStart) cutAt := bytes.LastIndex(buffer.Bytes(), tlsApplicationDataStart)
if cutAt == -1 { if cutAt == -1 {
cutAt = buf.BufferSize / 2 cutAt = xrayBufSize / 2
} }
buffer2 := buf.New() buffer2 := N.NewReadWaitOptions(nil, vc).NewBuffer() // ensure the new buffer can send used in vc.WriteBuffer
buffer2.Write(buffer.From(cutAt)) buffer2.Write(buffer.From(cutAt))
buffer.Truncate(cutAt) buffer.Truncate(cutAt)
return buffer2 return []*buf.Buffer{buffer, buffer2}
} }