-
Notifications
You must be signed in to change notification settings - Fork 10.7k
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
Implement google-c2p resolver. #25215
Conversation
cba6cef
to
80ede59
Compare
void* arg, grpc_error* error) { | ||
auto* self = static_cast<MetadataQuery*>(arg); | ||
self->MaybeCallOnDone(error); | ||
grpc_http_response_destroy(&self->response_); |
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.
This looks like a potentially use-after-free since we are destroying response_
here, but in MaybeCallDone
we just potentially passed it to a closure scheduled on the work serializer.
Any reason to not destroy response_
in the MetadataQuery
's dtor?
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.
Good catch! And yes, that's exactly the right fix. Done.
if (on_done_called_.CompareExchangeStrong( | ||
&expected, true, MemoryOrder::RELAXED, MemoryOrder::RELAXED)) { | ||
// Hop back into WorkSerializer. | ||
Ref().release(); // Ref held by callback. |
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.
If I'm correct, we need to ref error
here, since it's only current ref is the OnHttpRequestDone
closure, which may finish before the work serializer closure runs?
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.
Actually, I should have reffed it in the caller, because this function should take ownership of it, as per https://github.com/grpc/grpc/blob/master/doc/core/grpc-error.md#ownership-rules.
Fixed.
}, | ||
DEBUG_LOCATION); | ||
} else { | ||
GRPC_ERROR_UNREF(error); |
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.
related to above comment, isn't error
's only ref held by the OnHttpRequestDone
closure, so unreff'ing here is too much?
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 think the above fix covers this as well.
|
||
void GoogleCloud2ProdResolver::ZoneQueryDone(std::string zone) { | ||
zone_query_.reset(); | ||
zone_ = std::move(zone); |
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.
since in case of error we will be filling in zone_
with the empty string, does TD understand an empty string zone?
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.
Good point. I've changed the code to not set the locality at all if zone_
is the empty string.
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.
Thanks for the review!
void* arg, grpc_error* error) { | ||
auto* self = static_cast<MetadataQuery*>(arg); | ||
self->MaybeCallOnDone(error); | ||
grpc_http_response_destroy(&self->response_); |
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.
Good catch! And yes, that's exactly the right fix. Done.
if (on_done_called_.CompareExchangeStrong( | ||
&expected, true, MemoryOrder::RELAXED, MemoryOrder::RELAXED)) { | ||
// Hop back into WorkSerializer. | ||
Ref().release(); // Ref held by callback. |
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.
Actually, I should have reffed it in the caller, because this function should take ownership of it, as per https://github.com/grpc/grpc/blob/master/doc/core/grpc-error.md#ownership-rules.
Fixed.
}, | ||
DEBUG_LOCATION); | ||
} else { | ||
GRPC_ERROR_UNREF(error); |
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 think the above fix covers this as well.
|
||
void GoogleCloud2ProdResolver::ZoneQueryDone(std::string zone) { | ||
zone_query_.reset(); | ||
zone_ = std::move(zone); |
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.
Good point. I've changed the code to not set the locality at all if zone_
is the empty string.
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.
LGTM
The test failures both look like infrastructure issues. |
As part of this, I've changed the
Resolver
API such that the base class no longer takes ownership of theWorkSerializer
orResultHandler
. That will require internal changes, so I'll put together a cherry-pick for that once we're happy with this PR.I don't really have a good way to test the C2P resolver, but I'm hoping that you can put together an interop test that will cover it.