1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-09-09 05:26:39 -04:00
v2fly/proxy/vmess/io/reader.go

58 lines
1.2 KiB
Go
Raw Normal View History

2016-02-01 06:22:29 -05:00
package io
import (
"hash/fnv"
"io"
"github.com/v2ray/v2ray-core/common/alloc"
"github.com/v2ray/v2ray-core/common/serial"
"github.com/v2ray/v2ray-core/transport"
)
type AuthChunkReader struct {
reader io.Reader
}
func NewAuthChunkReader(reader io.Reader) *AuthChunkReader {
return &AuthChunkReader{
reader: reader,
}
}
func (this *AuthChunkReader) Read() (*alloc.Buffer, error) {
buffer := alloc.NewBuffer()
if _, err := io.ReadFull(this.reader, buffer.Value[:2]); err != nil {
buffer.Release()
return nil, err
}
length := serial.BytesLiteral(buffer.Value[:2]).Uint16Value()
2016-05-01 14:14:57 -04:00
if length <= 4 { // Length of authentication bytes.
2016-04-28 15:14:00 -04:00
return nil, io.EOF
}
2016-05-03 08:57:09 -04:00
if length > 8*1024-16 {
2016-05-01 14:14:57 -04:00
buffer.Release()
buffer = alloc.NewLargeBuffer()
}
2016-02-01 06:22:29 -05:00
if _, err := io.ReadFull(this.reader, buffer.Value[:length]); err != nil {
buffer.Release()
return nil, err
}
buffer.Slice(0, int(length))
fnvHash := fnv.New32a()
fnvHash.Write(buffer.Value[4:])
expAuth := serial.BytesLiteral(fnvHash.Sum(nil))
actualAuth := serial.BytesLiteral(buffer.Value[:4])
if !actualAuth.Equals(expAuth) {
buffer.Release()
return nil, transport.ErrorCorruptedPacket
}
buffer.SliceFrom(4)
return buffer, nil
}
2016-03-11 17:51:58 -05:00
func (this *AuthChunkReader) Release() {
this.reader = nil
}