tunnel: reduce allocation and improve performance (#1320)
* tunnel: reduce allocation and improve performance BenchmarkSha256Old-16 100000 156748 ns/op 11835 B/op 168 allocs/op BenchmarkSha256Old-16 100000 156229 ns/op 11819 B/op 168 allocs/op BenchmarkSha256New-16 100000 154751 ns/op 11107 B/op 161 allocs/op BenchmarkSha256New-16 100000 154263 ns/op 11110 B/op 161 allocs/op simple change lowers allocations and brings performance Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org> * fix Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org> * tunnel: reuse buf in Decrypt Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org> * fix unneeded conversations Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org> * base32 string is smaller than hex string Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
This commit is contained in:
parent
b344171c80
commit
43b0dbb123
@ -14,22 +14,17 @@ var (
|
||||
// gcmStandardNonceSize from crypto/cipher/gcm.go is 12 bytes
|
||||
// 100 - is max size of pool
|
||||
noncePool = bpool.NewBytePool(100, 12)
|
||||
hashPool = bpool.NewBytePool(1024*32, 32)
|
||||
)
|
||||
|
||||
// hash hahes the data into 32 bytes key and returns it
|
||||
// hash uses sha256 underneath to hash the supplied key
|
||||
func hash(key string) []byte {
|
||||
hasher := sha256.New()
|
||||
hasher.Write([]byte(key))
|
||||
out := hashPool.Get()
|
||||
defer hashPool.Put(out[:0])
|
||||
out = hasher.Sum(out[:0])
|
||||
return out
|
||||
func hash(key []byte) []byte {
|
||||
sum := sha256.Sum256(key)
|
||||
return sum[:]
|
||||
}
|
||||
|
||||
// Encrypt encrypts data and returns the encrypted data
|
||||
func Encrypt(data []byte, key string) ([]byte, error) {
|
||||
func Encrypt(data []byte, key []byte) ([]byte, error) {
|
||||
// generate a new AES cipher using our 32 byte key
|
||||
c, err := aes.NewCipher(hash(key))
|
||||
if err != nil {
|
||||
@ -59,7 +54,7 @@ func Encrypt(data []byte, key string) ([]byte, error) {
|
||||
}
|
||||
|
||||
// Decrypt decrypts the payload and returns the decrypted data
|
||||
func Decrypt(data []byte, key string) ([]byte, error) {
|
||||
func Decrypt(data []byte, key []byte) ([]byte, error) {
|
||||
// generate AES cipher for decrypting the message
|
||||
c, err := aes.NewCipher(hash(key))
|
||||
if err != nil {
|
||||
@ -81,10 +76,10 @@ func Decrypt(data []byte, key string) ([]byte, error) {
|
||||
// NOTE: we need to parse out nonce from the payload
|
||||
// we prepend the nonce to every encrypted payload
|
||||
nonce, ciphertext := data[:nonceSize], data[nonceSize:]
|
||||
plaintext, err := gcm.Open(nil, nonce, ciphertext, nil)
|
||||
ciphertext, err = gcm.Open(ciphertext[:0], nonce, ciphertext, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return plaintext, nil
|
||||
return ciphertext, nil
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import (
|
||||
)
|
||||
|
||||
func TestEncrypt(t *testing.T) {
|
||||
key := "tokenpassphrase"
|
||||
key := []byte("tokenpassphrase")
|
||||
data := []byte("supersecret")
|
||||
|
||||
cipherText, err := Encrypt(data, key)
|
||||
@ -21,7 +21,7 @@ func TestEncrypt(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDecrypt(t *testing.T) {
|
||||
key := "tokenpassphrase"
|
||||
key := []byte("tokenpassphrase")
|
||||
data := []byte("supersecret")
|
||||
|
||||
cipherText, err := Encrypt(data, key)
|
||||
|
@ -131,7 +131,7 @@ func (t *tun) newSession(channel, sessionId string) (*session, bool) {
|
||||
recv: make(chan *message, 128),
|
||||
send: t.send,
|
||||
errChan: make(chan error, 1),
|
||||
key: t.token + channel + sessionId,
|
||||
key: []byte(t.token + channel + sessionId),
|
||||
}
|
||||
|
||||
// save session
|
||||
|
@ -78,7 +78,7 @@ func (t *tunListener) process() {
|
||||
// create a new session session
|
||||
sess = &session{
|
||||
// the session key
|
||||
key: t.token + m.channel + sessionId,
|
||||
key: []byte(t.token + m.channel + sessionId),
|
||||
// the id of the remote side
|
||||
tunnel: m.tunnel,
|
||||
// the channel
|
||||
|
@ -1,7 +1,7 @@
|
||||
package tunnel
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"encoding/base32"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
@ -48,7 +48,7 @@ type session struct {
|
||||
// the error response
|
||||
errChan chan error
|
||||
// key for session encryption
|
||||
key string
|
||||
key []byte
|
||||
}
|
||||
|
||||
// message is sent over the send channel
|
||||
@ -348,8 +348,8 @@ func (s *session) Send(m *transport.Message) error {
|
||||
log.Debugf("failed to encrypt message header %s: %v", k, err)
|
||||
return err
|
||||
}
|
||||
// hex encode the encrypted header value
|
||||
data.Header[k] = hex.EncodeToString(val)
|
||||
// add the encrypted header value
|
||||
data.Header[k] = base32.StdEncoding.EncodeToString(val)
|
||||
}
|
||||
|
||||
// create a new message
|
||||
@ -391,33 +391,33 @@ func (s *session) Recv(m *transport.Message) error {
|
||||
|
||||
log.Tracef("Received %+v from recv backlog", msg)
|
||||
|
||||
key := s.token + s.channel + msg.session
|
||||
key := []byte(s.token + s.channel + msg.session)
|
||||
// decrypt the received payload using the token
|
||||
// we have to used msg.session because multicast has a shared
|
||||
// session id of "multicast" in this session struct on
|
||||
// the listener side
|
||||
body, err := Decrypt(msg.data.Body, key)
|
||||
msg.data.Body, err = Decrypt(msg.data.Body, key)
|
||||
if err != nil {
|
||||
log.Debugf("failed to decrypt message body: %v", err)
|
||||
return err
|
||||
}
|
||||
msg.data.Body = body
|
||||
|
||||
// encrypt all the headers
|
||||
// dencrypt all the headers
|
||||
for k, v := range msg.data.Header {
|
||||
// hex decode the header values
|
||||
h, err := hex.DecodeString(v)
|
||||
// decode the header values
|
||||
h, err := base32.StdEncoding.DecodeString(v)
|
||||
if err != nil {
|
||||
log.Debugf("failed to decode message header %s: %v", k, err)
|
||||
return err
|
||||
}
|
||||
// encrypt the transport message payload
|
||||
val, err := Decrypt([]byte(h), key)
|
||||
|
||||
// dencrypt the transport message payload
|
||||
val, err := Decrypt(h, key)
|
||||
if err != nil {
|
||||
log.Debugf("failed to decrypt message header %s: %v", k, err)
|
||||
return err
|
||||
}
|
||||
// hex encode the encrypted header value
|
||||
// add decrypted header value
|
||||
msg.data.Header[k] = string(val)
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user