fix: incomplete read filter in vision

This commit is contained in:
wwqgtxx 2025-09-10 02:32:01 +08:00
parent 318b3524c3
commit 23448ec119
2 changed files with 39 additions and 10 deletions

View File

@ -36,6 +36,7 @@ type Conn struct {
enableXTLS bool enableXTLS bool
cipher uint16 cipher uint16
remainingServerHello uint16 remainingServerHello uint16
readRemainingBuffer *buf.Buffer
readRemainingContent int readRemainingContent int
readRemainingPadding int readRemainingPadding int
readProcess bool readProcess bool
@ -56,23 +57,46 @@ func (vc *Conn) Read(b []byte) (int, error) {
} }
func (vc *Conn) ReadBuffer(buffer *buf.Buffer) error { func (vc *Conn) ReadBuffer(buffer *buf.Buffer) error {
if vc.readRemainingContent > 0 { if vc.readRemainingBuffer != nil {
toRead := buffer.FreeBytes() _, err := buffer.ReadOnceFrom(vc.readRemainingBuffer)
if vc.readRemainingContent < buffer.FreeLen() { if vc.readRemainingBuffer.IsEmpty() {
toRead = toRead[:vc.readRemainingContent] vc.readRemainingBuffer.Release()
vc.readRemainingBuffer = nil
} }
n, err := vc.ExtendedReader.Read(toRead) return err
buffer.Truncate(n) }
if vc.readRemainingContent > 0 {
readSize := xrayBufSize // at least read xrayBufSize
if buffer.FreeLen() > readSize { // input buffer larger than xrayBufSize, read as much as possible
readSize = buffer.FreeLen()
}
if readSize > vc.readRemainingContent { // don't read out of bounds
readSize = vc.readRemainingContent
}
readBuffer := buffer
if buffer.FreeLen() < readSize {
readBuffer = buf.NewSize(readSize)
vc.readRemainingBuffer = readBuffer
}
n, err := vc.ExtendedReader.Read(readBuffer.FreeBytes()[:readSize])
readBuffer.Truncate(n)
vc.readRemainingContent -= n vc.readRemainingContent -= n
vc.FilterTLS(toRead) vc.FilterTLS(readBuffer.Bytes())
if vc.readRemainingBuffer != nil {
innerErr := vc.ReadBuffer(buffer) // back to top but not losing err
if err != nil {
err = innerErr
}
}
return err return err
} }
if vc.readRemainingPadding > 0 { if vc.readRemainingPadding > 0 {
_, err := io.CopyN(io.Discard, vc.ExtendedReader, int64(vc.readRemainingPadding)) n, err := io.CopyN(io.Discard, vc.ExtendedReader, int64(vc.readRemainingPadding))
if err != nil { if err != nil {
return err return err
} }
vc.readRemainingPadding = 0 vc.readRemainingPadding -= int(n)
} }
if vc.readProcess { if vc.readProcess {
switch vc.readLastCommand { switch vc.readLastCommand {
@ -228,6 +252,10 @@ func (vc *Conn) NeedHandshake() bool {
return vc.writeOnceUserUUID != nil return vc.writeOnceUserUUID != nil
} }
func (vc *Conn) NeedAdditionalReadDeadline() bool {
return true
}
func (vc *Conn) Upstream() any { func (vc *Conn) Upstream() any {
if vc.writeDirect || if vc.writeDirect ||
vc.readLastCommand == commandPaddingDirect { vc.readLastCommand == commandPaddingDirect {

View File

@ -44,8 +44,9 @@ func ApplyPadding(buffer *buf.Buffer, command byte, userUUID *[]byte, paddingTLS
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 (vc *Conn) ReshapeBuffer(buffer *buf.Buffer) []*buf.Buffer {
const xrayBufSize = 8192 const xrayBufSize = 8192
func (vc *Conn) ReshapeBuffer(buffer *buf.Buffer) []*buf.Buffer {
if buffer.Len() <= xrayBufSize-PaddingHeaderLen { if buffer.Len() <= xrayBufSize-PaddingHeaderLen {
return []*buf.Buffer{buffer} return []*buf.Buffer{buffer}
} }