From 48f7cc213225ed5cf8a15dc34495dcffc577f5c0 Mon Sep 17 00:00:00 2001 From: yuhan6665 <1588741+yuhan6665@users.noreply.github.com> Date: Sun, 13 Nov 2022 12:18:23 -0500 Subject: [PATCH] Reshape multi buffer to fix the padding when buffer is full --- proxy/vless/encoding/encoding.go | 41 +++++++++++++++++++++++++++++++- proxy/vless/inbound/inbound.go | 2 +- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/proxy/vless/encoding/encoding.go b/proxy/vless/encoding/encoding.go index 9253ca5c..0b6d84e4 100644 --- a/proxy/vless/encoding/encoding.go +++ b/proxy/vless/encoding/encoding.go @@ -10,6 +10,7 @@ import ( "io" "math/big" "runtime" + "strconv" "syscall" "time" @@ -339,6 +340,7 @@ func XtlsWrite(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdate XtlsFilterTls13(buffer, numberOfPacketToFilter, isTLS13, isTLS12, isTLS, ctx) } if filterTlsApplicationData && *isTLS { + buffer = ReshapeMultiBuffer(ctx, buffer) var xtlsSpecIndex int for i, b := range buffer { if b.Len() >= 6 && bytes.Equal(tlsApplicationDataStart, b.BytesTo(3)) { @@ -428,6 +430,43 @@ func XtlsFilterTls13(buffer buf.MultiBuffer, numberOfPacketToFilter *int, isTLS1 } } +// ReshapeMultiBuffer prepare multi buffer for padding stucture (max 21 bytes) +func ReshapeMultiBuffer(ctx context.Context, buffer buf.MultiBuffer) buf.MultiBuffer { + needReshape := false + for _, b := range buffer { + if b.Len() >= buf.Size - 21 { + needReshape = true + } + } + if !needReshape { + return buffer; + } + mb2 := make(buf.MultiBuffer, 0, len(buffer)) + print := "" + for _, b := range buffer { + if b.Len() >= buf.Size - 21 { + index := int32(bytes.LastIndex(b.Bytes(), tlsApplicationDataStart)) + if index <= 0 { + index = buf.Size / 2 + } + buffer1 := buf.New() + buffer2 := buf.New() + buffer1.Write(b.BytesTo(index)) + buffer2.Write(b.BytesFrom(index)) + mb2 = append(mb2, buffer1, buffer2) + print += " " + strconv.Itoa(int(buffer1.Len())) + " " + strconv.Itoa(int(buffer2.Len())) + } else { + newbuffer := buf.New() + newbuffer.Write(b.Bytes()) + mb2 = append(mb2, newbuffer) + print += " " + strconv.Itoa(int(b.Len())) + } + } + buf.ReleaseMulti(buffer) + newError("ReshapeMultiBuffer ", print).WriteToLog(session.ExportIDToError(ctx)) + return mb2 +} + // XtlsPadding add padding to eliminate length siganature during tls handshake func XtlsPadding(b *buf.Buffer, command byte, userUUID *[]byte, ctx context.Context) *buf.Buffer { var length int32 = 0 @@ -480,7 +519,7 @@ func XtlsUnpadding(ctx context.Context, buffer buf.MultiBuffer, userUUID []byte, b := buffer[i] for posByte < b.Len() { if *remainingContent <= 0 && *remainingPadding <= 0 { - if *currentCommand == 1 { + if *currentCommand == 1 { // possible buffer after padding, no need to worry about xtls (command 2) len := b.Len() - posByte newbuffer := buf.New() newbuffer.Write(b.BytesRange(posByte, posByte+len)) diff --git a/proxy/vless/inbound/inbound.go b/proxy/vless/inbound/inbound.go index b791f880..1c90372a 100644 --- a/proxy/vless/inbound/inbound.go +++ b/proxy/vless/inbound/inbound.go @@ -563,8 +563,8 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s if requestAddons.Flow == vless.XRV { encoding.XtlsFilterTls13(multiBuffer, &numberOfPacketToFilter, &isTLS13, &isTLS12, &isTLS, ctx) if isTLS { + multiBuffer = encoding.ReshapeMultiBuffer(ctx, multiBuffer) for i, b := range multiBuffer { - multiBuffer[i] = encoding.XtlsPadding(b, 0x00, &userUUID, ctx) } }