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:
parent
1b2b5b6cb1
commit
55377d5ad5
@ -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
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user