diff --git a/proxy/proxy.go b/proxy/proxy.go index d2db4c73..29548d9f 100644 --- a/proxy/proxy.go +++ b/proxy/proxy.go @@ -256,13 +256,13 @@ func (w *VisionReader) ReadMultiBuffer() (buf.MultiBuffer, error) { } if *switchToDirectCopy { - // XTLS Vision processes TLS-like conn's input - // Only read from input (decrypted application data), not rawInput (encrypted TLS records) + // XTLS Vision processes TLS-like conn's input and rawInput if inputBuffer, err := buf.ReadFrom(w.input); err == nil && !inputBuffer.IsEmpty() { buffer, _ = buf.MergeMulti(buffer, inputBuffer) } - // Do not read from rawInput - it contains encrypted outer TLS records that would corrupt the stream - // Clear the buffers to release memory + if rawInputBuffer, err := buf.ReadFrom(w.rawInput); err == nil && !rawInputBuffer.IsEmpty() { + buffer, _ = buf.MergeMulti(buffer, rawInputBuffer) + } *w.input = bytes.Reader{} // release memory w.input = nil *w.rawInput = bytes.Buffer{} // release memory diff --git a/proxy/vless/outbound/outbound.go b/proxy/vless/outbound/outbound.go index a4fe1e93..f632ea54 100644 --- a/proxy/vless/outbound/outbound.go +++ b/proxy/vless/outbound/outbound.go @@ -275,6 +275,22 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte r, _ := t.FieldByName("rawInput") input = (*bytes.Reader)(unsafe.Pointer(p + i.Offset)) rawInput = (*bytes.Buffer)(unsafe.Pointer(p + r.Offset)) + // For pre-established connections, clear any buffered TLS control messages + // to prevent them from corrupting the Vision stream + if conn != nil { + // Drain input buffer (decrypted but unread application data) + if input != nil && input.Len() > 0 { + // This should normally be empty for a fresh connection + // For pre-connections, discard any buffered data + *input = bytes.Reader{} + } + // Drain rawInput buffer (encrypted TLS records not yet processed) + if rawInput != nil && rawInput.Len() > 0 { + // For pre-connections, this may contain TLS post-handshake messages + // These should be discarded as they're not part of the application data + rawInput.Reset() + } + } default: panic("unknown VLESS request command") }