-
Notifications
You must be signed in to change notification settings - Fork 4.5k
credentials/alts: Optimize reads #8204
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
f8e6f94
7a3308b
39712eb
0752372
be2e0bc
d9e52e4
3756c57
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,6 +26,7 @@ import ( | |
"math" | ||
"net" | ||
"reflect" | ||
"strings" | ||
"testing" | ||
|
||
core "google.golang.org/grpc/credentials/alts/internal" | ||
|
@@ -188,6 +189,48 @@ func (s) TestLargeMsg(t *testing.T) { | |
} | ||
} | ||
|
||
// TestLargeRecord writes a very large ALTS record and verifies that the server | ||
// receives it correctly. The large ALTS record should cause the reader to | ||
// expand it's read buffer to hold the entire record and store the decrypted | ||
// message until the receiver reads all of the bytes. | ||
func (s) TestLargeRecord(t *testing.T) { | ||
clientConn, serverConn := newConnPair(rekeyRecordProtocol, nil, nil) | ||
msg := []byte(strings.Repeat("a", 2*altsReadBufferInitialSize)) | ||
// Increase the size of ALTS records written by the client. | ||
clientConn.payloadLengthLimit = math.MaxInt32 | ||
if n, err := clientConn.Write(msg); n != len(msg) || err != nil { | ||
t.Fatalf("Write() = %v, %v; want %v, <nil>", n, err, len(msg)) | ||
} | ||
rcvMsg := make([]byte, len(msg)) | ||
if n, err := io.ReadFull(serverConn, rcvMsg); n != len(rcvMsg) || err != nil { | ||
t.Fatalf("Read() = %v, %v; want %v, <nil>", n, err, len(rcvMsg)) | ||
} | ||
if !reflect.DeepEqual(msg, rcvMsg) { | ||
t.Fatalf("Write()/Server Read() = %v, want %v", rcvMsg, msg) | ||
} | ||
} | ||
|
||
// BenchmarkLargeMessage measures the performance of ALTS conns for sending and | ||
// receiving a large message. | ||
func BenchmarkLargeMessage(b *testing.B) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @gtcooke94 Do we have any GitHub actions that already run these benchmarks or should we add any if not? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think someone else on the Go team would be the person to ask here - I don't know much about the CI setup. @arjan-bal do you know about the grpc-go github CI and benchmarking? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We don't run benchmarks as part of CI. We have benchmarks here that we ask PR authors to run when reviewing PRs that effect performance. We can have a similar benchmark for ALTS or modify the existing benchmark to support ALTS. We have performance dashboard for all languages here, but we don't have alerts setup for regressions: https://grafana-dot-grpc-testing.appspot.com/?orgId=1 |
||
msgLen := 20 * 1024 * 1024 // 20 MiB | ||
msg := make([]byte, msgLen) | ||
rcvMsg := make([]byte, len(msg)) | ||
b.ResetTimer() | ||
clientConn, serverConn := newConnPair(rekeyRecordProtocol, nil, nil) | ||
for range b.N { | ||
// Write 20 MiB 5 times to transfer a total of 100 MiB. | ||
for range 5 { | ||
if n, err := clientConn.Write(msg); n != len(msg) || err != nil { | ||
b.Fatalf("Write() = %v, %v; want %v, <nil>", n, err, len(msg)) | ||
} | ||
if n, err := io.ReadFull(serverConn, rcvMsg); n != len(rcvMsg) || err != nil { | ||
b.Fatalf("Read() = %v, %v; want %v, <nil>", n, err, len(rcvMsg)) | ||
} | ||
} | ||
} | ||
} | ||
|
||
func testIncorrectMsgType(t *testing.T, rp string) { | ||
// framedMsg is an empty ciphertext with correct framing but wrong | ||
// message type. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't get to review this very last changeset - here on 169 we make a specific length
int(length)+MsgLenFieldSize
, copy to it, then slice to a different var lengthlen(oldProtectedBuf)
I suspected something is not quite right here or can be made a little clearer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new buffer that we allocate must be able to hold the entire encrypted record. After reading the message header, we know the length of the record is:
length parsed from the message header
+size of the message length header
. This is the capacity, but the length of the new buffer should be set to the number of bytes that are already read. So we set the length to length of the existing buffer and copy its contents. Let me raise a PR with some commentry.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Created a PR to add clarity, PTAL: #8232