-
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
Expose internal/transport.GetConnection #5689
Comments
Did you consider implementing a |
Thanks @dfawley, that sounds like an excellent suggestion! We've indeed not previously been aware of this option. I'll try it out and if it works I'll close this issue. |
Works like a charm 🎉, thanks again @dfawley. For future reference, here is the gist of our implementation: type ConnectionStater interface {
ConnectionState() tls.ConnectionState
}
// PassThroughCredentials implements the grpc/credentials.TransportCredentials interface.
// It allows to pass the TLS connection state of an underlying TLS connection,
// e.g. from an underlying QUIC session, into the grpc stack. This allows accessing
// this information in the context of grpc/peer.Peer.AuthInfo.
// The handshake methods only extract the TLS state and otherwise simply
// pass-through the underlying connection object. The underlying connection
// must implement the ConnectionStater interface.
type PassThroughCredentials struct{}
func (c PassThroughCredentials) ClientHandshake(ctx context.Context, authority string, conn net.Conn) (net.Conn, credentials.AuthInfo, error) {
authInfo := credentials.TLSInfo{
State: conn.(ConnectionStater).ConnectionState(),
}
return conn, authInfo, nil
}
func (c PassThroughCredentials) ServerHandshake(conn net.Conn) (net.Conn, credentials.AuthInfo, error) {
authInfo := credentials.TLSInfo{
State: conn.(ConnectionStater).ConnectionState(),
}
return conn, authInfo, nil
}
func (c PassThroughCredentials) Info() credentials.ProtocolInfo {
return credentials.ProtocolInfo{
SecurityProtocol: "tls", // copied from grpc/credentials.tlsCreds.Info.
SecurityVersion: "1.2", // ditto
ServerName: "", // ?
}
}
func (c PassThroughCredentials) Clone() credentials.TransportCredentials {
return PassThroughCredentials{}
}
func (c PassThroughCredentials) OverrideServerName(string) error {
panic("not implemented")
} This can then be used in the setup of the server: grpc.NewServer(
grpc.Creds(PassThroughCredentials{}),
...
)
// use with a listener that returns a TLS connection and in the client: grpc.DialContext(ctx, addr.String(),
grpc.WithTransportCredentials(PassThroughCredentials{}),
...
// use a dialer that returns a TLS connection
) |
Use case(s) - what problem will this feature solve?
The request context contains the
net.Conn
connection object, but it's inaccessible for users of the library because the correspondingfunc GetConnection(context.Context) net.Con
function is in the internalinternal/transport
package.Accessing the connection object allows accessing advanced connection information. In particular, if the underlying connection is a TLS session (i.e. we're not using grpc-go's TLS, but the TLS is on the underlying connection), this allows accessing the session state so that it can be injected into the requests peer information.
Specifically, in our case we (have to) use QUIC underneath of grpc. We provide a
Listener
implementation that creates QUIC connections with a single stream, over which the grpc library then runs http2 (yes, this is a bit weird, but it's seemingly the best we can get without #906). We want to use the TLS state of the QUIC session for peer authentication and authorization. Accessing the connection object from an interceptor or service implementation is the only missing puzzle piece to make this work.Proposed Solution
Expose
GetConnection(context.Context) net.Conn
from a suitable non-internal package in the grpc library.Alternatives Considered
We have a workaround; we smuggle the
net.Conn
reference out via thenet.Addr
returned from our connectionsRemoteAddr() net.Addr
method. We can then extract this from thepeer.Peer.Addr
in a bespoke interceptor. This is obviously a bit a of a hack.Additional Context
This can be considered a workaround for #906.
The text was updated successfully, but these errors were encountered: