optimize encryption read/write operations

pull/1524/head^2
Darien Raymond 2018-07-31 12:37:59 +02:00
parent 8cfe77383f
commit 6a06908456
No known key found for this signature in database
GPG Key ID: 7251FFA14BB18169
5 changed files with 51 additions and 27 deletions

View File

@ -92,7 +92,7 @@ func NewWriter(writer io.Writer) Writer {
// NewSequentialWriter returns a Writer that write Buffers in a MultiBuffer sequentially. // NewSequentialWriter returns a Writer that write Buffers in a MultiBuffer sequentially.
func NewSequentialWriter(writer io.Writer) Writer { func NewSequentialWriter(writer io.Writer) Writer {
return &seqWriter{ return &SequentialWriter{
writer: writer, Writer: writer,
} }
} }

View File

@ -7,6 +7,22 @@ import (
"v2ray.com/core/common/errors" "v2ray.com/core/common/errors"
) )
func readOne(r io.Reader) (*Buffer, error) {
b := New()
for i := 0; i < 64; i++ {
err := b.Reset(ReadFrom(r))
if !b.IsEmpty() {
return b, nil
}
if err != nil {
b.Release()
return nil, err
}
}
return nil, newError("Reader returns too many empty payloads.")
}
// BytesToBufferReader is a Reader that adjusts its reading speed automatically. // BytesToBufferReader is a Reader that adjusts its reading speed automatically.
type BytesToBufferReader struct { type BytesToBufferReader struct {
io.Reader io.Reader
@ -21,22 +37,14 @@ func NewBytesToBufferReader(reader io.Reader) Reader {
} }
func (r *BytesToBufferReader) readSmall() (MultiBuffer, error) { func (r *BytesToBufferReader) readSmall() (MultiBuffer, error) {
b := New() b, err := readOne(r.Reader)
for i := 0; i < 64; i++ { if b.IsFull() && largeSize > Size {
err := b.Reset(ReadFrom(r.Reader)) r.buffer = newBytes(Size + 1)
if b.IsFull() && largeSize > Size {
r.buffer = newBytes(Size + 1)
}
if !b.IsEmpty() {
return NewMultiBufferValue(b), nil
}
if err != nil {
b.Release()
return nil, err
}
} }
if err != nil {
return nil, newError("Reader returns too many empty payloads.") return nil, err
}
return NewMultiBufferValue(b), nil
} }
func (r *BytesToBufferReader) freeBuffer() { func (r *BytesToBufferReader) freeBuffer() {
@ -195,3 +203,15 @@ func (r *BufferedReader) Close() error {
} }
return common.Close(r.Reader) return common.Close(r.Reader)
} }
type SingleReader struct {
io.Reader
}
func (r *SingleReader) ReadMultiBuffer() (MultiBuffer, error) {
b, err := readOne(r.Reader)
if err != nil {
return nil, err
}
return NewMultiBufferValue(b), nil
}

View File

@ -171,15 +171,15 @@ func (w *BufferedWriter) Close() error {
return common.Close(w.writer) return common.Close(w.writer)
} }
type seqWriter struct { type SequentialWriter struct {
writer io.Writer io.Writer
} }
func (w *seqWriter) WriteMultiBuffer(mb MultiBuffer) error { func (w *SequentialWriter) WriteMultiBuffer(mb MultiBuffer) error {
defer mb.Release() defer mb.Release()
for _, b := range mb { for _, b := range mb {
if err := WriteAllBytes(w.writer, b.Bytes()); err != nil { if err := WriteAllBytes(w.Writer, b.Bytes()); err != nil {
return err return err
} }
} }

View File

@ -172,10 +172,11 @@ func (r *AuthenticationReader) ReadMultiBuffer() (buf.MultiBuffer, error) {
return nil, err return nil, err
} }
mb := buf.NewMultiBufferCap(32) const readSize = 16
mb := buf.NewMultiBufferCap(readSize)
mb.Append(b) mb.Append(b)
for { for i := 1; i < readSize; i++ {
b, err := r.readInternal(true) b, err := r.readInternal(true)
if err == errSoft || err == io.EOF { if err == errSoft || err == io.EOF {
break break
@ -288,6 +289,7 @@ func (w *AuthenticationWriter) writePacket(mb buf.MultiBuffer) error {
return w.writer.WriteMultiBuffer(mb2Write) return w.writer.WriteMultiBuffer(mb2Write)
} }
// WriteMultiBuffer implements buf.Writer.
func (w *AuthenticationWriter) WriteMultiBuffer(mb buf.MultiBuffer) error { func (w *AuthenticationWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {
if mb.IsEmpty() { if mb.IsEmpty() {
b := buf.New() b := buf.New()

View File

@ -124,12 +124,14 @@ func (v *AesCfb) IVSize() int32 {
func (v *AesCfb) NewEncryptionWriter(key []byte, iv []byte, writer io.Writer) (buf.Writer, error) { func (v *AesCfb) NewEncryptionWriter(key []byte, iv []byte, writer io.Writer) (buf.Writer, error) {
stream := crypto.NewAesEncryptionStream(key, iv) stream := crypto.NewAesEncryptionStream(key, iv)
return buf.NewWriter(crypto.NewCryptionWriter(stream, writer)), nil return &buf.SequentialWriter{Writer: crypto.NewCryptionWriter(stream, writer)}, nil
} }
func (v *AesCfb) NewDecryptionReader(key []byte, iv []byte, reader io.Reader) (buf.Reader, error) { func (v *AesCfb) NewDecryptionReader(key []byte, iv []byte, reader io.Reader) (buf.Reader, error) {
stream := crypto.NewAesDecryptionStream(key, iv) stream := crypto.NewAesDecryptionStream(key, iv)
return buf.NewReader(crypto.NewCryptionReader(stream, reader)), nil return &buf.SingleReader{
Reader: crypto.NewCryptionReader(stream, reader),
}, nil
} }
func (v *AesCfb) EncodePacket(key []byte, b *buf.Buffer) error { func (v *AesCfb) EncodePacket(key []byte, b *buf.Buffer) error {
@ -243,12 +245,12 @@ func (v *ChaCha20) IVSize() int32 {
func (v *ChaCha20) NewEncryptionWriter(key []byte, iv []byte, writer io.Writer) (buf.Writer, error) { func (v *ChaCha20) NewEncryptionWriter(key []byte, iv []byte, writer io.Writer) (buf.Writer, error) {
stream := crypto.NewChaCha20Stream(key, iv) stream := crypto.NewChaCha20Stream(key, iv)
return buf.NewWriter(crypto.NewCryptionWriter(stream, writer)), nil return &buf.SequentialWriter{Writer: crypto.NewCryptionWriter(stream, writer)}, nil
} }
func (v *ChaCha20) NewDecryptionReader(key []byte, iv []byte, reader io.Reader) (buf.Reader, error) { func (v *ChaCha20) NewDecryptionReader(key []byte, iv []byte, reader io.Reader) (buf.Reader, error) {
stream := crypto.NewChaCha20Stream(key, iv) stream := crypto.NewChaCha20Stream(key, iv)
return buf.NewReader(crypto.NewCryptionReader(stream, reader)), nil return &buf.SingleReader{Reader: crypto.NewCryptionReader(stream, reader)}, nil
} }
func (v *ChaCha20) EncodePacket(key []byte, b *buf.Buffer) error { func (v *ChaCha20) EncodePacket(key []byte, b *buf.Buffer) error {