refactor protocol

pull/97/head
v2ray 2016-02-25 21:50:10 +01:00
parent 59bc881d70
commit 76ca9de25f
10 changed files with 39 additions and 71 deletions

View File

@ -6,22 +6,14 @@ import (
"io"
)
func NewAesDecryptionStream(key []byte, iv []byte) (cipher.Stream, error) {
aesBlock, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
return cipher.NewCFBDecrypter(aesBlock, iv), nil
func NewAesDecryptionStream(key []byte, iv []byte) cipher.Stream {
aesBlock, _ := aes.NewCipher(key)
return cipher.NewCFBDecrypter(aesBlock, iv)
}
func NewAesEncryptionStream(key []byte, iv []byte) (cipher.Stream, error) {
aesBlock, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
return cipher.NewCFBEncrypter(aesBlock, iv), nil
func NewAesEncryptionStream(key []byte, iv []byte) cipher.Stream {
aesBlock, _ := aes.NewCipher(key)
return cipher.NewCFBEncrypter(aesBlock, iv)
}
type cryptionReader struct {

View File

@ -35,7 +35,7 @@ func BenchmarkChaCha20IETF(b *testing.B) {
func BenchmarkAESEncryption(b *testing.B) {
key := make([]byte, 32)
iv := make([]byte, 16)
c, _ := NewAesEncryptionStream(key, iv)
c := NewAesEncryptionStream(key, iv)
benchmarkStream(b, c)
}
@ -43,7 +43,7 @@ func BenchmarkAESEncryption(b *testing.B) {
func BenchmarkAESDecryption(b *testing.B) {
key := make([]byte, 32)
iv := make([]byte, 16)
c, _ := NewAesDecryptionStream(key, iv)
c := NewAesDecryptionStream(key, iv)
benchmarkStream(b, c)
}

View File

@ -2,26 +2,24 @@ package protocol
import (
"io"
"github.com/v2ray/v2ray-core/common/alloc"
)
type RequestEncoder interface {
EncodeHeader(*RequestHeader) *alloc.Buffer
EncodeBody(io.Writer) io.Writer
EncodeRequestHeader(*RequestHeader, io.Writer)
EncodeRequestBody(io.Writer) io.Writer
}
type RequestDecoder interface {
DecodeHeader(io.Reader) *RequestHeader
DecodeBody(io.Reader) io.Reader
DecodeRequestHeader(io.Reader) *RequestHeader
DecodeRequestBody(io.Reader) io.Reader
}
type ResponseEncoder interface {
EncodeHeader(*ResponseHeader) *alloc.Buffer
EncodeBody(io.Writer) io.Writer
EncodeResponseHeader(*ResponseHeader, io.Writer)
EncodeResponseBody(io.Writer) io.Writer
}
type ResponseDecoder interface {
DecodeHeader(io.Reader) *ResponseHeader
DecodeBody(io.Reader) io.Reader
DecodeResponseHeader(io.Reader) *ResponseHeader
DecodeResponseBody(io.Reader) io.Reader
}

View File

@ -1,8 +1,10 @@
package protocol
import (
"crypto/hmac"
"crypto/md5"
"errors"
"hash"
"github.com/v2ray/v2ray-core/common/uuid"
)
@ -15,6 +17,12 @@ var (
InvalidID = errors.New("Invalid ID.")
)
type IDHash func(key []byte) hash.Hash
func DefaultIDHash(key []byte) hash.Hash {
return hmac.New(md5.New, key)
}
// The ID of en entity, in the form of an UUID.
type ID struct {
uuid *uuid.UUID

View File

@ -2,6 +2,7 @@ package protocol
import (
"math/rand"
"time"
"github.com/v2ray/v2ray-core/common/serial"
)
@ -14,6 +15,10 @@ func (this Timestamp) Bytes() []byte {
type TimestampGenerator func() Timestamp
func NowTime() Timestamp {
return Timestamp(time.Now().Unix())
}
func NewTimestampGenerator(base Timestamp, delta int) TimestampGenerator {
return func() Timestamp {
rangeInDelta := rand.Intn(delta*2) - delta

View File

@ -1,7 +1,6 @@
package protocol
import (
"hash"
"sync"
"time"
)
@ -11,8 +10,6 @@ const (
cacheDurationSec = 120
)
type IDHash func(key []byte) hash.Hash
type idEntry struct {
id *ID
userIdx int

View File

@ -28,18 +28,12 @@ func (this *AesCfb) IVSize() int {
}
func (this *AesCfb) NewEncodingStream(key []byte, iv []byte) (cipher.Stream, error) {
stream, err := crypto.NewAesEncryptionStream(key, iv)
if err != nil {
return nil, err
}
stream := crypto.NewAesEncryptionStream(key, iv)
return stream, nil
}
func (this *AesCfb) NewDecodingStream(key []byte, iv []byte) (cipher.Stream, error) {
stream, err := crypto.NewAesDecryptionStream(key, iv)
if err != nil {
return nil, err
}
stream := crypto.NewAesDecryptionStream(key, iv)
return stream, nil
}

View File

@ -147,13 +147,7 @@ func (this *VMessInboundHandler) HandleConnection(connection *hub.TCPConn) {
responseKey := md5.Sum(request.RequestKey)
responseIV := md5.Sum(request.RequestIV)
aesStream, err := v2crypto.NewAesEncryptionStream(responseKey[:], responseIV[:])
if err != nil {
log.Error("VMessIn: Failed to create AES decryption stream: ", err)
close(input)
return
}
aesStream := v2crypto.NewAesEncryptionStream(responseKey[:], responseIV[:])
responseWriter := v2crypto.NewCryptionWriter(aesStream, connection)
// Optimize for small response packet
@ -188,11 +182,7 @@ func handleInput(request *protocol.VMessRequest, reader io.Reader, input chan<-
defer close(input)
defer finish.Unlock()
aesStream, err := v2crypto.NewAesDecryptionStream(request.RequestKey, request.RequestIV)
if err != nil {
log.Error("VMessIn: Failed to create AES decryption stream: ", err)
return
}
aesStream := v2crypto.NewAesDecryptionStream(request.RequestKey, request.RequestIV)
descriptionReader := v2crypto.NewCryptionReader(aesStream, reader)
var requestReader v2io.Reader
if request.IsChunkStream() {

View File

@ -98,16 +98,12 @@ func (this *VMessOutboundHandler) startCommunicate(request *protocol.VMessReques
func (this *VMessOutboundHandler) handleRequest(conn net.Conn, request *protocol.VMessRequest, firstPacket v2net.Packet, input <-chan *alloc.Buffer, finish *sync.Mutex) {
defer finish.Unlock()
aesStream, err := v2crypto.NewAesEncryptionStream(request.RequestKey[:], request.RequestIV[:])
if err != nil {
log.Error("VMessOut: Failed to create AES encryption stream: ", err)
return
}
aesStream := v2crypto.NewAesEncryptionStream(request.RequestKey[:], request.RequestIV[:])
encryptRequestWriter := v2crypto.NewCryptionWriter(aesStream, conn)
buffer := alloc.NewBuffer().Clear()
defer buffer.Release()
buffer, err = request.ToBytes(proto.NewTimestampGenerator(proto.Timestamp(time.Now().Unix()), 30), buffer)
buffer, err := request.ToBytes(proto.NewTimestampGenerator(proto.Timestamp(time.Now().Unix()), 30), buffer)
if err != nil {
log.Error("VMessOut: Failed to serialize VMess request: ", err)
return
@ -160,16 +156,12 @@ func (this *VMessOutboundHandler) handleResponse(conn net.Conn, request *protoco
responseKey := md5.Sum(request.RequestKey[:])
responseIV := md5.Sum(request.RequestIV[:])
aesStream, err := v2crypto.NewAesDecryptionStream(responseKey[:], responseIV[:])
if err != nil {
log.Error("VMessOut: Failed to create AES encryption stream: ", err)
return
}
aesStream := v2crypto.NewAesDecryptionStream(responseKey[:], responseIV[:])
decryptResponseReader := v2crypto.NewCryptionReader(aesStream, conn)
buffer := alloc.NewSmallBuffer()
defer buffer.Release()
_, err = io.ReadFull(decryptResponseReader, buffer.Value[:4])
_, err := io.ReadFull(decryptResponseReader, buffer.Value[:4])
if err != nil {
log.Error("VMessOut: Failed to read VMess response (", buffer.Len(), " bytes): ", err)

View File

@ -100,12 +100,7 @@ func (this *VMessRequestReader) Read(reader io.Reader) (*VMessRequest, error) {
timestampHash := TimestampHash()
timestampHash.Write(hashTimestamp(timeSec))
iv := timestampHash.Sum(nil)
aesStream, err := v2crypto.NewAesDecryptionStream(userObj.ID.CmdKey(), iv)
if err != nil {
log.Debug("VMess: Failed to create AES stream: ", err)
return nil, err
}
aesStream := v2crypto.NewAesDecryptionStream(userObj.ID.CmdKey(), iv)
decryptor := v2crypto.NewCryptionReader(aesStream, reader)
nBytes, err = io.ReadFull(decryptor, buffer.Value[:41])
@ -235,10 +230,7 @@ func (this *VMessRequest) ToBytes(timestampGenerator proto.TimestampGenerator, b
timestampHash := md5.New()
timestampHash.Write(hashTimestamp(timestamp))
iv := timestampHash.Sum(nil)
aesStream, err := v2crypto.NewAesEncryptionStream(this.User.ID.CmdKey(), iv)
if err != nil {
return nil, err
}
aesStream := v2crypto.NewAesEncryptionStream(this.User.ID.CmdKey(), iv)
aesStream.XORKeyStream(buffer.Value[encryptionBegin:encryptionEnd], buffer.Value[encryptionBegin:encryptionEnd])
return buffer, nil