1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-12-22 10:08:15 -05:00
v2fly/proxy/vmess/io/reader.go
2016-03-11 23:51:58 +01:00

51 lines
1.1 KiB
Go

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()
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
}
func (this *AuthChunkReader) Release() {
this.reader = nil
}