Skip to content

Commit 23448ec

Browse files
committed
fix: incomplete read filter in vision
1 parent 318b352 commit 23448ec

File tree

2 files changed

+38
-9
lines changed

2 files changed

+38
-9
lines changed

transport/vless/vision/conn.go

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ type Conn struct {
3636
enableXTLS bool
3737
cipher uint16
3838
remainingServerHello uint16
39+
readRemainingBuffer *buf.Buffer
3940
readRemainingContent int
4041
readRemainingPadding int
4142
readProcess bool
@@ -56,23 +57,46 @@ func (vc *Conn) Read(b []byte) (int, error) {
5657
}
5758

5859
func (vc *Conn) ReadBuffer(buffer *buf.Buffer) error {
60+
if vc.readRemainingBuffer != nil {
61+
_, err := buffer.ReadOnceFrom(vc.readRemainingBuffer)
62+
if vc.readRemainingBuffer.IsEmpty() {
63+
vc.readRemainingBuffer.Release()
64+
vc.readRemainingBuffer = nil
65+
}
66+
return err
67+
}
5968
if vc.readRemainingContent > 0 {
60-
toRead := buffer.FreeBytes()
61-
if vc.readRemainingContent < buffer.FreeLen() {
62-
toRead = toRead[:vc.readRemainingContent]
69+
readSize := xrayBufSize // at least read xrayBufSize
70+
if buffer.FreeLen() > readSize { // input buffer larger than xrayBufSize, read as much as possible
71+
readSize = buffer.FreeLen()
72+
}
73+
if readSize > vc.readRemainingContent { // don't read out of bounds
74+
readSize = vc.readRemainingContent
75+
}
76+
77+
readBuffer := buffer
78+
if buffer.FreeLen() < readSize {
79+
readBuffer = buf.NewSize(readSize)
80+
vc.readRemainingBuffer = readBuffer
6381
}
64-
n, err := vc.ExtendedReader.Read(toRead)
65-
buffer.Truncate(n)
82+
n, err := vc.ExtendedReader.Read(readBuffer.FreeBytes()[:readSize])
83+
readBuffer.Truncate(n)
6684
vc.readRemainingContent -= n
67-
vc.FilterTLS(toRead)
85+
vc.FilterTLS(readBuffer.Bytes())
86+
if vc.readRemainingBuffer != nil {
87+
innerErr := vc.ReadBuffer(buffer) // back to top but not losing err
88+
if err != nil {
89+
err = innerErr
90+
}
91+
}
6892
return err
6993
}
7094
if vc.readRemainingPadding > 0 {
71-
_, err := io.CopyN(io.Discard, vc.ExtendedReader, int64(vc.readRemainingPadding))
95+
n, err := io.CopyN(io.Discard, vc.ExtendedReader, int64(vc.readRemainingPadding))
7296
if err != nil {
7397
return err
7498
}
75-
vc.readRemainingPadding = 0
99+
vc.readRemainingPadding -= int(n)
76100
}
77101
if vc.readProcess {
78102
switch vc.readLastCommand {
@@ -228,6 +252,10 @@ func (vc *Conn) NeedHandshake() bool {
228252
return vc.writeOnceUserUUID != nil
229253
}
230254

255+
func (vc *Conn) NeedAdditionalReadDeadline() bool {
256+
return true
257+
}
258+
231259
func (vc *Conn) Upstream() any {
232260
if vc.writeDirect ||
233261
vc.readLastCommand == commandPaddingDirect {

transport/vless/vision/padding.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,9 @@ func ApplyPadding(buffer *buf.Buffer, command byte, userUUID *[]byte, paddingTLS
4444
log.Debugln("XTLS Vision write padding: command=%d, payloadLen=%d, paddingLen=%d", command, contentLen, paddingLen)
4545
}
4646

47+
const xrayBufSize = 8192
48+
4749
func (vc *Conn) ReshapeBuffer(buffer *buf.Buffer) []*buf.Buffer {
48-
const xrayBufSize = 8192
4950
if buffer.Len() <= xrayBufSize-PaddingHeaderLen {
5051
return []*buf.Buffer{buffer}
5152
}

0 commit comments

Comments
 (0)