@@ -5,8 +5,10 @@ import (
55 "encoding/binary"
66 "hash/fnv"
77 "io"
8+ "io/ioutil"
89 "sync"
910 "time"
11+ "v2ray.com/core/common/dice"
1012
1113 "golang.org/x/crypto/chacha20poly1305"
1214
@@ -194,7 +196,13 @@ func (s *ServerSession) DecodeRequestHeader(reader io.Reader) (*protocol.Request
194196 expectedHash := binary .BigEndian .Uint32 (buffer .BytesFrom (- 4 ))
195197
196198 if actualHash != expectedHash {
197- return nil , newError ("invalid auth" )
199+ //It is possible that we are under attack described in https://github.com/v2ray/v2ray-core/issues/2523
200+ //We read a deterministic generated length of data before closing the connection to offset padding read pattern
201+ drainSum := dice .RollDeterministic (48 , int64 (actualHash ))
202+ if err := s .DrainConnN (reader , drainSum ); err != nil {
203+ return nil , newError ("invalid auth, failed to drain connection" ).Base (err )
204+ }
205+ return nil , newError ("invalid auth, connection drained" )
198206 }
199207
200208 if request .Address == nil {
@@ -347,3 +355,8 @@ func (s *ServerSession) EncodeResponseBody(request *protocol.RequestHeader, writ
347355 panic ("Unknown security type." )
348356 }
349357}
358+
359+ func (s * ServerSession ) DrainConnN (reader io.Reader , n int ) error {
360+ _ , err := io .CopyN (ioutil .Discard , reader , int64 (n ))
361+ return err
362+ }
0 commit comments