diff --git a/cmd/protoc-gen-go-grpc/go.mod b/cmd/protoc-gen-go-grpc/go.mod index 88ce30d67b47..5182dd832504 100644 --- a/cmd/protoc-gen-go-grpc/go.mod +++ b/cmd/protoc-gen-go-grpc/go.mod @@ -1,6 +1,6 @@ module google.golang.org/grpc/cmd/protoc-gen-go-grpc -go 1.23.0 +go 1.24.0 require ( google.golang.org/grpc v1.70.0 diff --git a/credentials/alts/internal/conn/common.go b/credentials/alts/internal/conn/common.go index 46617132a456..d4c3ab7989f7 100644 --- a/credentials/alts/internal/conn/common.go +++ b/credentials/alts/internal/conn/common.go @@ -19,9 +19,7 @@ package conn import ( - "encoding/binary" "errors" - "fmt" ) const ( @@ -48,33 +46,3 @@ func SliceForAppend(in []byte, n int) (head, tail []byte) { tail = head[len(in):] return head, tail } - -// ParseFramedMsg parse the provided buffer and returns a frame of the format -// msgLength+msg and any remaining bytes in that buffer. -func ParseFramedMsg(b []byte, maxLen uint32) ([]byte, []byte, error) { - // If the size field is not complete, return the provided buffer as - // remaining buffer. - length, sufficientBytes := parseMessageLength(b) - if !sufficientBytes { - return nil, b, nil - } - if length > maxLen { - return nil, nil, fmt.Errorf("received the frame length %d larger than the limit %d", length, maxLen) - } - if len(b) < int(length)+4 { // account for the first 4 msg length bytes. - // Frame is not complete yet. - return nil, b, nil - } - return b[:MsgLenFieldSize+length], b[MsgLenFieldSize+length:], nil -} - -// parseMessageLength returns the message length based on frame header. It also -// returns a boolean indicating if the buffer contains sufficient bytes to parse -// the length header. If there are insufficient bytes, (0, false) is returned. -func parseMessageLength(b []byte) (uint32, bool) { - if len(b) < MsgLenFieldSize { - return 0, false - } - msgLenField := b[:MsgLenFieldSize] - return binary.LittleEndian.Uint32(msgLenField), true -} diff --git a/credentials/alts/internal/conn/record.go b/credentials/alts/internal/conn/record.go index f9d2646d4b22..aa893d91c354 100644 --- a/credentials/alts/internal/conn/record.go +++ b/credentials/alts/internal/conn/record.go @@ -56,17 +56,12 @@ const ( MsgLenFieldSize = 4 // The byte size of the message type field of a framed message. msgTypeFieldSize = 4 - // The bytes size limit for a ALTS record message. + // The bytes size limit for an ALTS record message. altsRecordLengthLimit = 1024 * 1024 // 1 MiB - // The default bytes size of a ALTS record message. - altsRecordDefaultLength = 4 * 1024 // 4KiB // Message type value included in ALTS record framing. altsRecordMsgType = uint32(0x06) // The initial write buffer size. altsWriteBufferInitialSize = 32 * 1024 // 32KiB - // The maximum write buffer size. This *must* be multiple of - // altsRecordDefaultLength. - altsWriteBufferMaxSize = 512 * 1024 // 512KiB // The initial buffer used to read from the network. altsReadBufferInitialSize = 32 * 1024 // 32KiB ) @@ -116,7 +111,7 @@ func NewConn(c net.Conn, side core.Side, recordProtocol string, key []byte, prot return nil, fmt.Errorf("protocol %q: %v", recordProtocol, err) } overhead := MsgLenFieldSize + msgTypeFieldSize + crypto.EncryptionOverhead() - payloadLengthLimit := altsRecordDefaultLength - overhead + payloadLengthLimit := altsRecordLengthLimit - overhead // We pre-allocate protected to be of size 32KB during initialization. // We increase the size of the buffer by the required amount if it can't // hold a complete encrypted record. @@ -144,7 +139,7 @@ func NewConn(c net.Conn, side core.Side, recordProtocol string, key []byte, prot func (p *conn) Read(b []byte) (n int, err error) { if len(p.buf) == 0 { var framedMsg []byte - framedMsg, p.nextFrame, err = ParseFramedMsg(p.nextFrame, altsRecordLengthLimit) + framedMsg, err = p.parseFramedMsg(p.nextFrame, altsRecordLengthLimit) if err != nil { return n, err } @@ -184,7 +179,7 @@ func (p *conn) Read(b []byte) (n int, err error) { return 0, err } p.protected = p.protected[:len(p.protected)+n] - framedMsg, p.nextFrame, err = ParseFramedMsg(p.protected, altsRecordLengthLimit) + framedMsg, err = p.parseFramedMsg(p.protected, altsRecordLengthLimit) if err != nil { return 0, err } @@ -225,6 +220,38 @@ func (p *conn) Read(b []byte) (n int, err error) { return n, nil } +// parseFramedMsg parses the provided buffer and returns a frame of the format +// msgLength+msg iff a full frame is available. +func (p *conn) parseFramedMsg(b []byte, maxLen uint32) ([]byte, error) { + // If the size field is not complete, return the provided buffer as + // remaining buffer. + p.nextFrame = b + length, sufficientBytes := parseMessageLength(b) + if !sufficientBytes { + return nil, nil + } + if length > maxLen { + return nil, fmt.Errorf("received the frame length %d larger than the limit %d", length, maxLen) + } + if len(b) < int(length)+4 { // account for the first 4 msg length bytes. + // Frame is not complete yet. + return nil, nil + } + p.nextFrame = b[MsgLenFieldSize+length:] + return b[:MsgLenFieldSize+length], nil +} + +// parseMessageLength returns the message length based on frame header. It also +// returns a boolean indicating if the buffer contains sufficient bytes to parse +// the length header. If there are insufficient bytes, (0, false) is returned. +func parseMessageLength(b []byte) (uint32, bool) { + if len(b) < MsgLenFieldSize { + return 0, false + } + msgLenField := b[:MsgLenFieldSize] + return binary.LittleEndian.Uint32(msgLenField), true +} + // Write encrypts, frames, and writes bytes from b to the underlying connection. func (p *conn) Write(b []byte) (n int, err error) { n = len(b) @@ -233,10 +260,9 @@ func (p *conn) Write(b []byte) (n int, err error) { size := len(b) + numOfFrames*p.overhead // If writeBuf is too small, increase its size up to the maximum size. partialBSize := len(b) - if size > altsWriteBufferMaxSize { - size = altsWriteBufferMaxSize - const numOfFramesInMaxWriteBuf = altsWriteBufferMaxSize / altsRecordDefaultLength - partialBSize = numOfFramesInMaxWriteBuf * p.payloadLengthLimit + if size > altsRecordLengthLimit { + size = altsRecordLengthLimit + partialBSize = p.payloadLengthLimit } if len(p.writeBuf) < size { p.writeBuf = make([]byte, size) @@ -282,7 +308,7 @@ func (p *conn) Write(b []byte) (n int, err error) { // written. This means we need to remove header, // encryption overheads, and any partially-written // frame data. - numOfWrittenFrames := int(math.Floor(float64(nn) / float64(altsRecordDefaultLength))) + numOfWrittenFrames := int(math.Floor(float64(nn) / float64(altsRecordLengthLimit))) return partialBStart + numOfWrittenFrames*p.payloadLengthLimit, err } } diff --git a/credentials/alts/internal/conn/record_test.go b/credentials/alts/internal/conn/record_test.go index e4992489a189..477dccc22907 100644 --- a/credentials/alts/internal/conn/record_test.go +++ b/credentials/alts/internal/conn/record_test.go @@ -168,8 +168,8 @@ func (s) TestSmallReadBuffer(t *testing.T) { func testLargeMsg(t *testing.T, rp string) { clientConn, serverConn := newConnPair(rp, nil, nil) // msgLen is such that the length in the framing is larger than the - // default size of one frame. - msgLen := altsRecordDefaultLength - msgTypeFieldSize - clientConn.crypto.EncryptionOverhead() + 1 + // max size of one frame. + msgLen := altsRecordLengthLimit - msgTypeFieldSize - clientConn.crypto.EncryptionOverhead() + 1 msg := make([]byte, msgLen) if n, err := clientConn.Write(msg); n != len(msg) || err != nil { t.Fatalf("Write() = %v, %v; want %v, ", n, err, len(msg)) @@ -292,7 +292,7 @@ func testWriteLargeData(t *testing.T, rp string) { clientConn, serverConn := newConnPair(rp, nil, nil) // Message size is intentionally chosen to not be multiple of // payloadLengthLimit. - msgSize := altsWriteBufferMaxSize + (100 * 1024) + msgSize := altsRecordLengthLimit + (100 * 1024) clientMsg := make([]byte, msgSize) for i := 0; i < msgSize; i++ { clientMsg[i] = 0xAA diff --git a/examples/go.mod b/examples/go.mod index b9a0905e89e7..9f9aef89b7b6 100644 --- a/examples/go.mod +++ b/examples/go.mod @@ -1,6 +1,6 @@ module google.golang.org/grpc/examples -go 1.23.0 +go 1.24.0 require ( github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443 diff --git a/gcp/observability/go.mod b/gcp/observability/go.mod index d766a4ecd93f..2172f53afdaf 100644 --- a/gcp/observability/go.mod +++ b/gcp/observability/go.mod @@ -1,6 +1,6 @@ module google.golang.org/grpc/gcp/observability -go 1.23.0 +go 1.24.0 require ( cloud.google.com/go/logging v1.13.0 diff --git a/go.mod b/go.mod index 2ded5df83a4f..a9926f6d9757 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module google.golang.org/grpc -go 1.23.0 +go 1.24.0 require ( github.com/cespare/xxhash/v2 v2.3.0 diff --git a/interop/observability/go.mod b/interop/observability/go.mod index 48f04f389e0b..f9f70e0687ad 100644 --- a/interop/observability/go.mod +++ b/interop/observability/go.mod @@ -1,6 +1,6 @@ module google.golang.org/grpc/interop/observability -go 1.23.0 +go 1.24.0 require ( google.golang.org/grpc v1.73.0 diff --git a/interop/xds/go.mod b/interop/xds/go.mod index 0f67f0d3ca5b..8b4a31d6f21a 100644 --- a/interop/xds/go.mod +++ b/interop/xds/go.mod @@ -1,6 +1,6 @@ module google.golang.org/grpc/interop/xds -go 1.23.0 +go 1.24.0 replace google.golang.org/grpc => ../.. diff --git a/scripts/vet.sh b/scripts/vet.sh index 18c4085fce54..402e589c5fe2 100755 --- a/scripts/vet.sh +++ b/scripts/vet.sh @@ -97,7 +97,7 @@ for MOD_FILE in $(find . -name 'go.mod'); do gofmt -s -d -l . 2>&1 | fail_on_output goimports -l . 2>&1 | not grep -vE "\.pb\.go" - go mod tidy -compat=1.23 + go mod tidy -compat=1.24 git status --porcelain 2>&1 | fail_on_output || \ (git status; git --no-pager diff; exit 1) diff --git a/security/advancedtls/examples/go.mod b/security/advancedtls/examples/go.mod index b159aa5a7353..21efee72221d 100644 --- a/security/advancedtls/examples/go.mod +++ b/security/advancedtls/examples/go.mod @@ -1,6 +1,6 @@ module google.golang.org/grpc/security/advancedtls/examples -go 1.23.0 +go 1.24.0 require ( google.golang.org/grpc v1.73.0 diff --git a/security/advancedtls/go.mod b/security/advancedtls/go.mod index 89ee48feb77b..5321cc579d21 100644 --- a/security/advancedtls/go.mod +++ b/security/advancedtls/go.mod @@ -1,6 +1,6 @@ module google.golang.org/grpc/security/advancedtls -go 1.23.0 +go 1.24.0 require ( github.com/google/go-cmp v0.7.0 diff --git a/stats/opencensus/go.mod b/stats/opencensus/go.mod index 8b258ddc4c13..8c56d9b23272 100644 --- a/stats/opencensus/go.mod +++ b/stats/opencensus/go.mod @@ -1,6 +1,6 @@ module google.golang.org/grpc/stats/opencensus -go 1.23.0 +go 1.24.0 require ( github.com/google/go-cmp v0.7.0 diff --git a/test/tools/go.mod b/test/tools/go.mod index 4c8f58edac60..7c8341315c69 100644 --- a/test/tools/go.mod +++ b/test/tools/go.mod @@ -1,6 +1,6 @@ module google.golang.org/grpc/test/tools -go 1.23.0 +go 1.24.0 require ( github.com/client9/misspell v0.3.4