1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2025-07-26 11:44:22 -04:00

refactor protocol

This commit is contained in:
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" "io"
) )
func NewAesDecryptionStream(key []byte, iv []byte) (cipher.Stream, error) { func NewAesDecryptionStream(key []byte, iv []byte) cipher.Stream {
aesBlock, err := aes.NewCipher(key) aesBlock, _ := aes.NewCipher(key)
if err != nil { return cipher.NewCFBDecrypter(aesBlock, iv)
return nil, err
} }
return cipher.NewCFBDecrypter(aesBlock, iv), nil func NewAesEncryptionStream(key []byte, iv []byte) cipher.Stream {
} aesBlock, _ := aes.NewCipher(key)
return cipher.NewCFBEncrypter(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
} }
type cryptionReader struct { type cryptionReader struct {

View File

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

View File

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

View File

@ -1,8 +1,10 @@
package protocol package protocol
import ( import (
"crypto/hmac"
"crypto/md5" "crypto/md5"
"errors" "errors"
"hash"
"github.com/v2ray/v2ray-core/common/uuid" "github.com/v2ray/v2ray-core/common/uuid"
) )
@ -15,6 +17,12 @@ var (
InvalidID = errors.New("Invalid ID.") 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. // The ID of en entity, in the form of an UUID.
type ID struct { type ID struct {
uuid *uuid.UUID uuid *uuid.UUID

View File

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

View File

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

View File

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

View File

@ -147,13 +147,7 @@ func (this *VMessInboundHandler) HandleConnection(connection *hub.TCPConn) {
responseKey := md5.Sum(request.RequestKey) responseKey := md5.Sum(request.RequestKey)
responseIV := md5.Sum(request.RequestIV) responseIV := md5.Sum(request.RequestIV)
aesStream, err := v2crypto.NewAesEncryptionStream(responseKey[:], responseIV[:]) aesStream := v2crypto.NewAesEncryptionStream(responseKey[:], responseIV[:])
if err != nil {
log.Error("VMessIn: Failed to create AES decryption stream: ", err)
close(input)
return
}
responseWriter := v2crypto.NewCryptionWriter(aesStream, connection) responseWriter := v2crypto.NewCryptionWriter(aesStream, connection)
// Optimize for small response packet // Optimize for small response packet
@ -188,11 +182,7 @@ func handleInput(request *protocol.VMessRequest, reader io.Reader, input chan<-
defer close(input) defer close(input)
defer finish.Unlock() defer finish.Unlock()
aesStream, err := v2crypto.NewAesDecryptionStream(request.RequestKey, request.RequestIV) aesStream := v2crypto.NewAesDecryptionStream(request.RequestKey, request.RequestIV)
if err != nil {
log.Error("VMessIn: Failed to create AES decryption stream: ", err)
return
}
descriptionReader := v2crypto.NewCryptionReader(aesStream, reader) descriptionReader := v2crypto.NewCryptionReader(aesStream, reader)
var requestReader v2io.Reader var requestReader v2io.Reader
if request.IsChunkStream() { 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) { func (this *VMessOutboundHandler) handleRequest(conn net.Conn, request *protocol.VMessRequest, firstPacket v2net.Packet, input <-chan *alloc.Buffer, finish *sync.Mutex) {
defer finish.Unlock() defer finish.Unlock()
aesStream, err := v2crypto.NewAesEncryptionStream(request.RequestKey[:], request.RequestIV[:]) aesStream := v2crypto.NewAesEncryptionStream(request.RequestKey[:], request.RequestIV[:])
if err != nil {
log.Error("VMessOut: Failed to create AES encryption stream: ", err)
return
}
encryptRequestWriter := v2crypto.NewCryptionWriter(aesStream, conn) encryptRequestWriter := v2crypto.NewCryptionWriter(aesStream, conn)
buffer := alloc.NewBuffer().Clear() buffer := alloc.NewBuffer().Clear()
defer buffer.Release() 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 { if err != nil {
log.Error("VMessOut: Failed to serialize VMess request: ", err) log.Error("VMessOut: Failed to serialize VMess request: ", err)
return return
@ -160,16 +156,12 @@ func (this *VMessOutboundHandler) handleResponse(conn net.Conn, request *protoco
responseKey := md5.Sum(request.RequestKey[:]) responseKey := md5.Sum(request.RequestKey[:])
responseIV := md5.Sum(request.RequestIV[:]) responseIV := md5.Sum(request.RequestIV[:])
aesStream, err := v2crypto.NewAesDecryptionStream(responseKey[:], responseIV[:]) aesStream := v2crypto.NewAesDecryptionStream(responseKey[:], responseIV[:])
if err != nil {
log.Error("VMessOut: Failed to create AES encryption stream: ", err)
return
}
decryptResponseReader := v2crypto.NewCryptionReader(aesStream, conn) decryptResponseReader := v2crypto.NewCryptionReader(aesStream, conn)
buffer := alloc.NewSmallBuffer() buffer := alloc.NewSmallBuffer()
defer buffer.Release() defer buffer.Release()
_, err = io.ReadFull(decryptResponseReader, buffer.Value[:4]) _, err := io.ReadFull(decryptResponseReader, buffer.Value[:4])
if err != nil { if err != nil {
log.Error("VMessOut: Failed to read VMess response (", buffer.Len(), " bytes): ", err) 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 := TimestampHash()
timestampHash.Write(hashTimestamp(timeSec)) timestampHash.Write(hashTimestamp(timeSec))
iv := timestampHash.Sum(nil) iv := timestampHash.Sum(nil)
aesStream, err := v2crypto.NewAesDecryptionStream(userObj.ID.CmdKey(), iv) aesStream := v2crypto.NewAesDecryptionStream(userObj.ID.CmdKey(), iv)
if err != nil {
log.Debug("VMess: Failed to create AES stream: ", err)
return nil, err
}
decryptor := v2crypto.NewCryptionReader(aesStream, reader) decryptor := v2crypto.NewCryptionReader(aesStream, reader)
nBytes, err = io.ReadFull(decryptor, buffer.Value[:41]) nBytes, err = io.ReadFull(decryptor, buffer.Value[:41])
@ -235,10 +230,7 @@ func (this *VMessRequest) ToBytes(timestampGenerator proto.TimestampGenerator, b
timestampHash := md5.New() timestampHash := md5.New()
timestampHash.Write(hashTimestamp(timestamp)) timestampHash.Write(hashTimestamp(timestamp))
iv := timestampHash.Sum(nil) iv := timestampHash.Sum(nil)
aesStream, err := v2crypto.NewAesEncryptionStream(this.User.ID.CmdKey(), iv) aesStream := v2crypto.NewAesEncryptionStream(this.User.ID.CmdKey(), iv)
if err != nil {
return nil, err
}
aesStream.XORKeyStream(buffer.Value[encryptionBegin:encryptionEnd], buffer.Value[encryptionBegin:encryptionEnd]) aesStream.XORKeyStream(buffer.Value[encryptionBegin:encryptionEnd], buffer.Value[encryptionBegin:encryptionEnd])
return buffer, nil return buffer, nil