mirror of
https://github.com/XTLS/Xray-core.git
synced 2026-06-27 23:43:06 +00:00
Fix occasional SSL protocol error in XTLS Vision by deferring direct copy when rawInput has pending data
Co-authored-by: RPRX <63339210+RPRX@users.noreply.github.com>
This commit is contained in:
+11
-3
@@ -224,7 +224,8 @@ func (w *VisionReader) ReadMultiBuffer() (buf.MultiBuffer, error) {
|
|||||||
switchToDirectCopy = &w.trafficState.Outbound.DownlinkReaderDirectCopy
|
switchToDirectCopy = &w.trafficState.Outbound.DownlinkReaderDirectCopy
|
||||||
}
|
}
|
||||||
|
|
||||||
if *switchToDirectCopy {
|
if *switchToDirectCopy && w.input == nil {
|
||||||
|
// Already switched to direct copy mode
|
||||||
if w.directReadCounter != nil {
|
if w.directReadCounter != nil {
|
||||||
w.directReadCounter.Add(int64(buffer.Len()))
|
w.directReadCounter.Add(int64(buffer.Len()))
|
||||||
}
|
}
|
||||||
@@ -257,11 +258,18 @@ func (w *VisionReader) ReadMultiBuffer() (buf.MultiBuffer, error) {
|
|||||||
|
|
||||||
if *switchToDirectCopy {
|
if *switchToDirectCopy {
|
||||||
// XTLS Vision processes TLS-like conn's input and rawInput
|
// XTLS Vision processes TLS-like conn's input and rawInput
|
||||||
|
// input contains decrypted application data - safe to merge
|
||||||
if inputBuffer, err := buf.ReadFrom(w.input); err == nil && !inputBuffer.IsEmpty() {
|
if inputBuffer, err := buf.ReadFrom(w.input); err == nil && !inputBuffer.IsEmpty() {
|
||||||
buffer, _ = buf.MergeMulti(buffer, inputBuffer)
|
buffer, _ = buf.MergeMulti(buffer, inputBuffer)
|
||||||
}
|
}
|
||||||
if rawInputBuffer, err := buf.ReadFrom(w.rawInput); err == nil && !rawInputBuffer.IsEmpty() {
|
// rawInput may contain encrypted bytes for the next TLS record
|
||||||
buffer, _ = buf.MergeMulti(buffer, rawInputBuffer)
|
// If rawInput is not empty, we should NOT switch to direct mode yet
|
||||||
|
// because those bytes need to be processed by the TLS layer first
|
||||||
|
if w.rawInput != nil && w.rawInput.Len() > 0 {
|
||||||
|
// rawInput has pending data - defer direct copy to next read
|
||||||
|
// Keep *switchToDirectCopy as true so we retry on next read
|
||||||
|
// This ensures we don't mix encrypted bytes with application data
|
||||||
|
return buffer, err
|
||||||
}
|
}
|
||||||
*w.input = bytes.Reader{} // release memory
|
*w.input = bytes.Reader{} // release memory
|
||||||
w.input = nil
|
w.input = nil
|
||||||
|
|||||||
Reference in New Issue
Block a user