Skip to content
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

grpc: fix receiving empty messages when compression is enabled and maxReceiveMessageSize is maxInt64 #7753 #7918

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

vinothkumarr227
Copy link

@vinothkumarr227 vinothkumarr227 commented Dec 10, 2024

Fixes #4552

RELEASE NOTES:

  • grpc: fix receiving empty messages when compression is enabled and maxReceiveMessageSize is maxInt64

@arjan-bal arjan-bal self-requested a review December 11, 2024 11:09
@arjan-bal arjan-bal self-assigned this Dec 11, 2024
@arjan-bal arjan-bal added Area: RPC Features Includes Compression, Encoding, Attributes/Metadata, Interceptors. Type: Bug and removed Area: RPC Features Includes Compression, Encoding, Attributes/Metadata, Interceptors. labels Dec 11, 2024
@arjan-bal arjan-bal added this to the 1.70 Release milestone Dec 11, 2024
Copy link

codecov bot commented Dec 12, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 82.12%. Comparing base (4c07bca) to head (19686ab).
Report is 19 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #7918      +/-   ##
==========================================
+ Coverage   81.84%   82.12%   +0.27%     
==========================================
  Files         377      378       +1     
  Lines       38120    38269     +149     
==========================================
+ Hits        31201    31428     +227     
+ Misses       5603     5542      -61     
+ Partials     1316     1299      -17     
Files with missing lines Coverage Δ
rpc_util.go 79.89% <100.00%> (+0.57%) ⬆️

... and 38 files with indirect coverage changes

rpc_util.go Outdated
if err != nil {
out.Free()
return nil, 0, err
}
if err = checkReceiveMessageOverflow(int64(out.Len()), int64(maxReceiveMessageSize), dcReader); err != nil {
return nil, out.Len() + 1, err
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding 1 to out.Len() can result in an overflow on 32 bit systems. The following part of the function seems strange to me:

Optionally, if data will be over maxReceiveMessageSize, just return the size

I suggest making the following change to avoid this:

  1. Declare a global error for indicating that the max receive size is exceeded:
var	errMaxMessageSizeExceeded = errors.New("max message size exceeded")
  1. When the check here fails, nil, 0, errMaxMessageSizeExceeded. Update the godoc to mention the same.
  2. In the caller, i.e. recvAndDecompress, instead of checking if size > maxReceiveMessageSize, check if err == errMaxMessageSizeExceeded. Also update the error message to not mention the actual size, because we didn't read the entire message anyways: grpc: received message after decompression larger than max %d.

This ensures we're using the returned error to indicate the failure instead of relying on special values of the bytes read count.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please let the reviewer resolve comments.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should not attempt to add out.Len() + 1, instead return errMaxMessageSizeExceeded to signal the same.

rpc_util.go Outdated Show resolved Hide resolved
rpc_util.go Outdated
// If additional data is read, or an error other than `io.EOF` is encountered, the function
// returns an error indicating that the message size has exceeded the permissible limit.
func checkReceiveMessageOverflow(readBytes, maxReceiveMessageSize int64, dcReader io.Reader) error {
if readBytes == maxReceiveMessageSize {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can invert this check and returns early to reduce indentation.

if readBytes < maxReceiveMessageSize {
   return nil
}

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I fixed all the comments.

rpc_util.go Outdated Show resolved Hide resolved
rpc_util.go Outdated Show resolved Hide resolved
rpc_util.go Outdated Show resolved Hide resolved
rpc_util.go Outdated Show resolved Hide resolved
rpc_util.go Outdated Show resolved Hide resolved
rpc_util.go Outdated
if err != nil {
out.Free()
return nil, 0, err
}
if err = checkReceiveMessageOverflow(int64(out.Len()), int64(maxReceiveMessageSize), dcReader); err != nil {
return nil, out.Len() + 1, err
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please let the reviewer resolve comments.

rpc_util.go Outdated
if err != nil {
out.Free()
return nil, 0, err
}
if err = checkReceiveMessageOverflow(int64(out.Len()), int64(maxReceiveMessageSize), dcReader); err != nil {
return nil, out.Len() + 1, err
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should not attempt to add out.Len() + 1, instead return errMaxMessageSizeExceeded to signal the same.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Get empty response when compress enabled and maxReceiveMessageSize be maxInt64
2 participants