authenticator

pull/82/head
v2ray 9 years ago
parent 494f431c37
commit 06b92bddcf

@ -5,6 +5,12 @@ import (
"sync" "sync"
) )
func Release(buffer *Buffer) {
if buffer != nil {
buffer.Release()
}
}
// Buffer is a recyclable allocation of a byte array. Buffer.Release() recycles // Buffer is a recyclable allocation of a byte array. Buffer.Release() recycles
// the buffer into an internal buffer pool, in order to recreate a buffer more // the buffer into an internal buffer pool, in order to recreate a buffer more
// quickly. // quickly.

@ -0,0 +1,6 @@
package crypto
type Authenticator interface {
AuthBytes() int
Authenticate(auth []byte, data []byte) []byte
}

@ -4,6 +4,9 @@ import (
"io" "io"
"github.com/v2ray/v2ray-core/common/alloc" "github.com/v2ray/v2ray-core/common/alloc"
"github.com/v2ray/v2ray-core/common/crypto"
"github.com/v2ray/v2ray-core/common/serial"
"github.com/v2ray/v2ray-core/transport"
) )
// ReadFrom reads from a reader and put all content to a buffer. // ReadFrom reads from a reader and put all content to a buffer.
@ -17,6 +20,42 @@ func ReadFrom(reader io.Reader, buffer *alloc.Buffer) (*alloc.Buffer, error) {
return buffer, err return buffer, err
} }
func ReadChunk(reader io.Reader, buffer *alloc.Buffer) (*alloc.Buffer, error) {
if buffer == nil {
buffer = alloc.NewBuffer()
}
if _, err := io.ReadFull(reader, buffer.Value[:2]); err != nil {
alloc.Release(buffer)
return nil, err
}
length := serial.BytesLiteral(buffer.Value[:2]).Uint16Value()
if _, err := io.ReadFull(reader, buffer.Value[:length]); err != nil {
alloc.Release(buffer)
return nil, err
}
buffer.Slice(0, int(length))
return buffer, nil
}
func ReadAuthenticatedChunk(reader io.Reader, auth crypto.Authenticator, buffer *alloc.Buffer) (*alloc.Buffer, error) {
buffer, err := ReadChunk(reader, buffer)
if err != nil {
alloc.Release(buffer)
return nil, err
}
authSize := auth.AuthBytes()
authBytes := auth.Authenticate(nil, buffer.Value[authSize:])
if !serial.BytesLiteral(authBytes).Equals(serial.BytesLiteral(buffer.Value[:authSize])) {
alloc.Release(buffer)
return nil, transport.CorruptedPacket
}
buffer.SliceFrom(authSize)
return buffer, nil
}
// ReaderToChan dumps all content from a given reader to a chan by constantly reading it until EOF. // ReaderToChan dumps all content from a given reader to a chan by constantly reading it until EOF.
func ReaderToChan(stream chan<- *alloc.Buffer, reader io.Reader) error { func ReaderToChan(stream chan<- *alloc.Buffer, reader io.Reader) error {
allocate := alloc.NewBuffer allocate := alloc.NewBuffer

@ -1,5 +1,9 @@
package serial package serial
import (
"bytes"
)
type Bytes interface { type Bytes interface {
Bytes() []byte Bytes() []byte
} }
@ -10,6 +14,10 @@ func (this BytesLiteral) Value() []byte {
return []byte(this) return []byte(this)
} }
func (this BytesLiteral) Equals(another BytesLiteral) bool {
return bytes.Equal(this.Value(), another.Value())
}
func (this BytesLiteral) Uint8Value() uint8 { func (this BytesLiteral) Uint8Value() uint8 {
return this.Value()[0] return this.Value()[0]
} }

Loading…
Cancel
Save