@@ -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
5859func (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+
231259func (vc * Conn ) Upstream () any {
232260 if vc .writeDirect ||
233261 vc .readLastCommand == commandPaddingDirect {
0 commit comments