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:
parent
59bc881d70
commit
76ca9de25f
@ -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 {
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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() {
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user