@@ -350,10 +350,11 @@ func (w *VisionWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {
350350 mb [0 ] = XtlsPadding (nil , CommandPaddingContinue , & w .writeOnceUserUUID , true , w .ctx ) // we do a long padding to hide vless header
351351 return w .Writer .WriteMultiBuffer (mb )
352352 }
353+ isComplete := IsCompleteRecord (mb )
353354 mb = ReshapeMultiBuffer (w .ctx , mb )
354355 longPadding := w .trafficState .IsTLS
355356 for i , b := range mb {
356- if w .trafficState .IsTLS && b .Len () >= 6 && bytes .Equal (TlsApplicationDataStart , b .BytesTo (3 )) {
357+ if w .trafficState .IsTLS && b .Len () >= 6 && bytes .Equal (TlsApplicationDataStart , b .BytesTo (3 )) && isComplete {
357358 if w .trafficState .EnableXtls {
358359 * switchToDirectCopy = true
359360 }
@@ -386,6 +387,71 @@ func (w *VisionWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {
386387 return w .Writer .WriteMultiBuffer (mb )
387388}
388389
390+ // IsCompleteRecord Is complete tls data record
391+ func IsCompleteRecord (buffer buf.MultiBuffer ) bool {
392+ mb2 := make (buf.MultiBuffer , 0 , len (buffer ))
393+ for _ , buffer1 := range buffer {
394+ buffer2 := buf .New ()
395+ buffer2 .Write (buffer1 .Bytes ())
396+ mb2 = append (mb2 , buffer2 )
397+ }
398+ isComplete := true
399+ var headerLen int32 = 5
400+ var recordLen int32
401+ for _ , buffer2 := range mb2 {
402+ for buffer2 .Len () > 0 {
403+ if headerLen > 0 {
404+ data , _ := buffer2 .ReadByte ()
405+ switch headerLen {
406+ case 5 :
407+ if data != 0x17 {
408+ isComplete = false
409+ break
410+ }
411+ case 4 :
412+ if data != 0x03 {
413+ isComplete = false
414+ break
415+ }
416+ case 3 :
417+ if data != 0x03 {
418+ isComplete = false
419+ break
420+ }
421+ case 2 :
422+ recordLen = int32 (data ) << 8
423+ case 1 :
424+ recordLen = recordLen | int32 (data )
425+ }
426+ headerLen --
427+ } else if recordLen > 0 {
428+ var len = recordLen
429+ if buffer2 .Len () < recordLen {
430+ len = buffer2 .Len ()
431+ }
432+ buffer2 .Advance (len )
433+ recordLen -= len
434+ if recordLen == 0 {
435+ headerLen = 5
436+ }
437+ } else {
438+ isComplete = false
439+ }
440+ }
441+ if ! isComplete {
442+ break
443+ }
444+ }
445+ for _ , buffer2 := range mb2 {
446+ buffer2 .Release ()
447+ buffer2 = nil
448+ }
449+ if headerLen == 5 && recordLen == 0 && isComplete {
450+ return true
451+ }
452+ return false
453+ }
454+
389455// ReshapeMultiBuffer prepare multi buffer for padding structure (max 21 bytes)
390456func ReshapeMultiBuffer (ctx context.Context , buffer buf.MultiBuffer ) buf.MultiBuffer {
391457 needReshape := 0
0 commit comments