1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-11-04 17:27:23 -05:00

Send VMess request along with first data packet for performance

This commit is contained in:
V2Ray 2015-09-17 23:26:09 +02:00
parent 1b2b5b6cb1
commit 55377d5ad5
5 changed files with 43 additions and 42 deletions

View File

@ -6,7 +6,7 @@ import (
"io" "io"
) )
func NewAesDecryptReader(key []byte, iv []byte, reader io.Reader) (io.Reader, error) { func NewAesDecryptReader(key []byte, iv []byte, reader io.Reader) (*CryptionReader, error) {
aesBlock, err := aes.NewCipher(key) aesBlock, err := aes.NewCipher(key)
if err != nil { if err != nil {
return nil, err return nil, err
@ -16,7 +16,7 @@ func NewAesDecryptReader(key []byte, iv []byte, reader io.Reader) (io.Reader, er
return NewCryptionReader(aesStream, reader), nil return NewCryptionReader(aesStream, reader), nil
} }
func NewAesEncryptWriter(key []byte, iv []byte, writer io.Writer) (io.Writer, error) { func NewAesEncryptWriter(key []byte, iv []byte, writer io.Writer) (*CryptionWriter, error) {
aesBlock, err := aes.NewCipher(key) aesBlock, err := aes.NewCipher(key)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -48,9 +48,13 @@ func NewCryptionWriter(stream cipher.Stream, writer io.Writer) *CryptionWriter {
} }
} }
func (writer CryptionWriter) Crypt(blocks []byte) {
writer.stream.XORKeyStream(blocks, blocks)
}
// Write writes the give blocks to underlying writer. The length of the blocks // Write writes the give blocks to underlying writer. The length of the blocks
// must be a multiply of BlockSize() // must be a multiply of BlockSize()
func (writer CryptionWriter) Write(blocks []byte) (int, error) { func (writer CryptionWriter) Write(blocks []byte) (int, error) {
writer.stream.XORKeyStream(blocks, blocks) writer.Crypt(blocks)
return writer.writer.Write(blocks) return writer.writer.Write(blocks)
} }

View File

@ -181,26 +181,14 @@ func (r *VMessRequestReader) Read(reader io.Reader) (*VMessRequest, error) {
return request, nil return request, nil
} }
type VMessRequestWriter struct { func (request *VMessRequest) ToBytes(idHash v2hash.CounterHash, randomRangeInt64 v2math.RandomInt64InRange) ([]byte, error) {
idHash v2hash.CounterHash
randomRangeInt64 v2math.RandomInt64InRange
}
func NewVMessRequestWriter(idHash v2hash.CounterHash, randomRangeInt64 v2math.RandomInt64InRange) *VMessRequestWriter {
return &VMessRequestWriter{
idHash: idHash,
randomRangeInt64: randomRangeInt64,
}
}
func (w *VMessRequestWriter) Write(writer io.Writer, request *VMessRequest) error {
buffer := make([]byte, 0, 300) buffer := make([]byte, 0, 300)
counter := w.randomRangeInt64(time.Now().UTC().Unix(), 30) counter := randomRangeInt64(time.Now().UTC().Unix(), 30)
idHash := w.idHash.Hash(request.UserId.Bytes, counter) hash := idHash.Hash(request.UserId.Bytes, counter)
log.Debug("Writing userhash: %v", idHash) log.Debug("Writing userhash: %v", hash)
buffer = append(buffer, idHash...) buffer = append(buffer, hash...)
encryptionBegin := len(buffer) encryptionBegin := len(buffer)
@ -208,7 +196,7 @@ func (w *VMessRequestWriter) Write(writer io.Writer, request *VMessRequest) erro
randomContent := make([]byte, randomLength) randomContent := make([]byte, randomLength)
_, err := rand.Read(randomContent) _, err := rand.Read(randomContent)
if err != nil { if err != nil {
return err return nil, err
} }
buffer = append(buffer, byte(randomLength)) buffer = append(buffer, byte(randomLength))
buffer = append(buffer, randomContent...) buffer = append(buffer, randomContent...)
@ -240,7 +228,7 @@ func (w *VMessRequestWriter) Write(writer io.Writer, request *VMessRequest) erro
paddingBuffer := make([]byte, paddingLength) paddingBuffer := make([]byte, paddingLength)
_, err = rand.Read(paddingBuffer) _, err = rand.Read(paddingBuffer)
if err != nil { if err != nil {
return err return nil, err
} }
buffer = append(buffer, byte(paddingLength)) buffer = append(buffer, byte(paddingLength))
buffer = append(buffer, paddingBuffer...) buffer = append(buffer, paddingBuffer...)
@ -248,21 +236,12 @@ func (w *VMessRequestWriter) Write(writer io.Writer, request *VMessRequest) erro
aesCipher, err := aes.NewCipher(request.UserId.CmdKey()) aesCipher, err := aes.NewCipher(request.UserId.CmdKey())
if err != nil { if err != nil {
return err return nil, err
} }
aesStream := cipher.NewCFBEncrypter(aesCipher, v2hash.Int64Hash(counter)) aesStream := cipher.NewCFBEncrypter(aesCipher, v2hash.Int64Hash(counter))
cWriter := v2io.NewCryptionWriter(aesStream, writer) aesStream.XORKeyStream(buffer[encryptionBegin:encryptionEnd], buffer[encryptionBegin:encryptionEnd])
_, err = writer.Write(buffer[0:encryptionBegin]) return buffer, nil
if err != nil {
return err
}
_, err = cWriter.Write(buffer[encryptionBegin:encryptionEnd])
if err != nil {
return err
}
return nil
} }
type VMessResponse [4]byte type VMessResponse [4]byte

View File

@ -77,6 +77,7 @@ func (handler *VMessInboundHandler) HandleConnection(connection net.Conn) error
if err != nil { if err != nil {
return log.Error("Failed to create encrypt writer: %v", err) return log.Error("Failed to create encrypt writer: %v", err)
} }
//responseWriter.Write(response[:])
// Optimize for small response packet // Optimize for small response packet
buffer := make([]byte, 0, 1024) buffer := make([]byte, 0, 1024)
@ -87,7 +88,11 @@ func (handler *VMessInboundHandler) HandleConnection(connection net.Conn) error
} }
responseWriter.Write(buffer) responseWriter.Write(buffer)
go handleOutput(request, responseWriter, output, writeFinish) if open {
go handleOutput(request, responseWriter, output, writeFinish)
} else {
close(writeFinish)
}
<-writeFinish <-writeFinish
if tcpConn, ok := connection.(*net.TCPConn); ok { if tcpConn, ok := connection.(*net.TCPConn); ok {

View File

@ -98,19 +98,32 @@ func startCommunicate(request *vmessio.VMessRequest, dest v2net.Address, ray cor
func handleRequest(conn *net.TCPConn, request *vmessio.VMessRequest, input <-chan []byte, finish chan<- bool) error { func handleRequest(conn *net.TCPConn, request *vmessio.VMessRequest, input <-chan []byte, finish chan<- bool) error {
defer close(finish) defer close(finish)
requestWriter := vmessio.NewVMessRequestWriter(v2hash.NewTimeHash(v2hash.HMACHash{}), v2math.GenerateRandomInt64InRange)
err := requestWriter.Write(conn, request)
if err != nil {
log.Error("Failed to write VMess request: %v", err)
return err
}
encryptRequestWriter, err := v2io.NewAesEncryptWriter(request.RequestKey[:], request.RequestIV[:], conn) encryptRequestWriter, err := v2io.NewAesEncryptWriter(request.RequestKey[:], request.RequestIV[:], conn)
if err != nil { if err != nil {
log.Error("Failed to create encrypt writer: %v", err) log.Error("Failed to create encrypt writer: %v", err)
return err return err
} }
buffer, err := request.ToBytes(v2hash.NewTimeHash(v2hash.HMACHash{}), v2math.GenerateRandomInt64InRange)
if err != nil {
log.Error("VMessOut: Failed to serialize VMess request: %v", err)
}
//conn.Write(buffer)
data, open := <-input
if open {
encryptRequestWriter.Crypt(data)
buffer = append(buffer, data...)
}
_, err = conn.Write(buffer)
if err != nil {
log.Error("VMessOut: Failed to write VMess request: %v", err)
}
if !open {
return nil
}
v2net.ChanToWriter(encryptRequestWriter, input) v2net.ChanToWriter(encryptRequestWriter, input)
return nil return nil
} }