Merge pull request #780 from Roasbeef/brontide-reduce-allocs

brontide: reduce memory allocs by using static buf for next header+msg
This commit is contained in:
Olaoluwa Osuntokun 2018-02-26 13:04:27 -08:00 committed by GitHub
commit 94746c2d12
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -345,6 +345,20 @@ type Machine struct {
ephemeralGen func() (*btcec.PrivateKey, error)
handshakeState
// nextCipherHeader is a static buffer that we'll use to read in the
// next ciphertext header from the wire. The header is a 2 byte length
// (of the next ciphertext), followed by a 16 byte MAC.
nextCipherHeader [lengthHeaderSize + macSize]byte
// nextCipherText is a static buffer that we'll use to read in the
// bytes of the next cipher text message. As all messages in the
// protocol MUST be below 65KB plus our macSize, this will be
// sufficient to buffer all messages from the socket when we need to
// read the next one. Having a fixed buffer that's re-used also means
// that we save on allocations as we don't need to create a new one
// each time.
nextCipherText [math.MaxUint16 + macSize]byte
}
// NewBrontideMachine creates a new instance of the brontide state-machine. If
@ -698,25 +712,25 @@ func (b *Machine) WriteMessage(w io.Writer, p []byte) error {
// ReadMessage attempts to read the next message from the passed io.Reader. In
// the case of an authentication error, a non-nil error is returned.
func (b *Machine) ReadMessage(r io.Reader) ([]byte, error) {
var cipherLen [lengthHeaderSize + macSize]byte
if _, err := io.ReadFull(r, cipherLen[:]); err != nil {
if _, err := io.ReadFull(r, b.nextCipherHeader[:]); err != nil {
return nil, err
}
// Attempt to decrypt+auth the packet length present in the stream.
pktLenBytes, err := b.recvCipher.Decrypt(nil, nil, cipherLen[:])
pktLenBytes, err := b.recvCipher.Decrypt(
nil, nil, b.nextCipherHeader[:],
)
if err != nil {
return nil, err
}
// Next, using the length read from the packet header, read the
// encrypted packet itself.
var cipherText [math.MaxUint16 + macSize]byte
pktLen := uint32(binary.BigEndian.Uint16(pktLenBytes)) + macSize
if _, err := io.ReadFull(r, cipherText[:pktLen]); err != nil {
if _, err := io.ReadFull(r, b.nextCipherText[:pktLen]); err != nil {
return nil, err
}
// TODO(roasbeef): modify to let pass in slice
return b.recvCipher.Decrypt(nil, nil, cipherText[:pktLen])
return b.recvCipher.Decrypt(nil, nil, b.nextCipherText[:pktLen])
}