-
Notifications
You must be signed in to change notification settings - Fork 4.4k
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
transport: new stream with actual server name #5748
transport: new stream with actual server name #5748
Conversation
|
I agree with the spirit of these changes, but I'd like to propose an alternate implementation. A little background:
My proposed fix is as follows:
The only reason I want to make a copy of the Making the change in |
…r matches server name used in TLS handshake when the latter is overridden by the name resolver
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.
Changes look mostly good to me. Just some minor nits.
internal/transport/http2_client.go
Outdated
dupCallHdr := *callHdr | ||
// ServerName field of the resolver returned address takes precedence over | ||
// Host field of CallHdr to determine the :authority header. This is because, | ||
// the ServerName field takes precedence for server authentication during | ||
// TLS handshake, and the :authority header should match the value used | ||
// for server authentication. | ||
if t.address.ServerName != "" { | ||
dupCallHdr.Host = t.address.ServerName | ||
} |
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.
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 that's the right call; otherwise if you reuse callHdr
across multiple attempts for one RPC, and one transport has an authority set and another doesn't, then you could end up with the wrong behavior.
Can we avoid making this copy, though, if there is no change?
if t.address.ServerName != "" {
newCallHdr := *callHdr
newCallHdr.Host = t.address.ServerName
callHdr = &newCallHdr
}
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 your advice, it looks better.
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.
Thank you for the contribution!
ServerName field of the resolver returned address takes precedence over Host field of CallHdr to determine the :authority header. Refer to grpc/grpc-go#5748 Signed-off-by: Benjamin Wang <wachao@vmware.com>
Hey, this change popped up in etcd e2e testing as upgrading grpc to v1.52 changed authority sent by etcd client https://github.com/etcd-io/etcd/pull/15131/files#r1071931813. Context: Etcd uses grpc resolver to implement loadbalancing and we had issues in grpc < v1.51 as authority didn't work with resolver. We implemented a hack to fix this #4717. The difference we noticed is fact that authority header sent in v1.52 doesn't include port even though URI contains it. This is described in https://www.rfc-editor.org/rfc/rfc3986#section-3.2. For I'm not an expert in this area, so please advise what should be the correct authority header. |
@serathius what are you setting |
Sure, https://github.com/etcd-io/etcd/blob/main/client/v3/internal/resolver/resolver.go |
Sorry, I'm not really able to follow everything, here, as there is a lot of conditional logic going into setting the Also, note that these APIs are documented as being experimental and unstable, and I'm worried that any changes we make here in the future will break you and your users and cause problems just like the ones we had in the past. We would strongly recommend against using any of these APIs ( |
Previously etcd was depending on gRPC 1.51, and the authority is Line 1625 in ce56cef
But the We (etcd) have two options for now,
I followed option 1 above for now. Please let me know if you have any concerns. |
I'm not sure which way is the right one for you, but I am 90% sure that using a different I'm still concerned about your usage of these APIs. Maybe one day we can chat about your use cases and see if there's some other way to accomplish what you're doing using stable APIs. We will be changing these APIs, and unless something is done ahead of time, or in a coordinated fashion, your users will be broken again. |
Thanks @dfawley . I just raised a ticket in etcd to track the task of removing the dependency on the experimental APIs. Could you share more info/doc on this, such as what's the alternative solution? |
I would need to know more about what your goals and requirements are in order to suggest a solution. We may be able to provide a higher level API that you could use if we don't have something that meets your needs already. |
We will think about this and get back to you when needed. Thanks again. |
When the resolver-address backend is an HAProxy, we invoked gRPC-methods and got 'code = Internal desc = stream terminated by RST_STREAM with error code: PROTOCOL_ERROR', the reason is header value of ': authority' is not matched in HAProxy.
Example: resolver scheme is 'xxx:///serviceName/methodName', resolver return an HAProxy address like 'grpc-proxy.xxx.com:80', but current transport used to target 'serviceName/methodName' as ':authority' header value, when do invoke, HAProxy is not known which endpoint we need to request.
RELEASE NOTES:
:authority
header matches server name used in TLS handshake when the latter is overridden by the name resolver