Merge pull request #186 from iamqizhao/master
Allow some handshaking between client and server before rpc happens.
This commit is contained in:
Коммит
5ea2bfc402
|
@ -104,6 +104,15 @@ func WithDialer(f func(addr string, timeout time.Duration) (net.Conn, error)) Di
|
|||
}
|
||||
}
|
||||
|
||||
// WithHandshaker returns a DialOption that specifies a function to perform some handshaking
|
||||
// with the server. It is typically used to negotiate the wire protocol version and security
|
||||
// protocol with the server.
|
||||
func WithHandshaker(h func(conn net.Conn) (credentials.TransportAuthenticator, error)) DialOption {
|
||||
return func(o *dialOptions) {
|
||||
o.copts.Handshaker = h
|
||||
}
|
||||
}
|
||||
|
||||
// Dial creates a client connection the given target.
|
||||
// TODO(zhaoq): Have an option to make Dial return immediately without waiting
|
||||
// for connection to complete.
|
||||
|
|
|
@ -70,8 +70,19 @@ type Credentials interface {
|
|||
GetRequestMetadata(ctx context.Context) (map[string]string, error)
|
||||
}
|
||||
|
||||
// TransportAuthenticator defines the common interface all supported transport
|
||||
// authentication protocols (e.g., TLS, SSL) must implement.
|
||||
// ProtocolInfo provides information regarding the gRPC wire protocol version,
|
||||
// security protocol, security protocol version in use, etc.
|
||||
type ProtocolInfo struct {
|
||||
// ProtocolVersion is the gRPC wire protocol version.
|
||||
ProtocolVersion string
|
||||
// SecurityProtocol is the security protocol in use.
|
||||
SecurityProtocol string
|
||||
// SecurityVersion is the security protocol version.
|
||||
SecurityVersion string
|
||||
}
|
||||
|
||||
// TransportAuthenticator defines the common interface for all the live gRPC wire
|
||||
// protocols and supported transport security protocols (e.g., TLS, SSL).
|
||||
type TransportAuthenticator interface {
|
||||
// Handshake does the authentication handshake specified by the corresponding
|
||||
// authentication protocol on rawConn.
|
||||
|
@ -79,6 +90,8 @@ type TransportAuthenticator interface {
|
|||
// NewListener creates a listener which accepts connections with requested
|
||||
// authentication handshake.
|
||||
NewListener(lis net.Listener) net.Listener
|
||||
// Info provides the ProtocolInfo of this TransportAuthenticator.
|
||||
Info() ProtocolInfo
|
||||
Credentials
|
||||
}
|
||||
|
||||
|
@ -88,6 +101,13 @@ type tlsCreds struct {
|
|||
config tls.Config
|
||||
}
|
||||
|
||||
func (c *tlsCreds) Info() ProtocolInfo {
|
||||
return ProtocolInfo{
|
||||
SecurityProtocol: "tls",
|
||||
SecurityVersion: "1.2",
|
||||
}
|
||||
}
|
||||
|
||||
// GetRequestMetadata returns nil, nil since TLS credentials does not have
|
||||
// metadata.
|
||||
func (c *tlsCreds) GetRequestMetadata(ctx context.Context) (map[string]string, error) {
|
||||
|
|
|
@ -111,6 +111,17 @@ func newHTTP2Client(addr string, opts *ConnectOptions) (_ ClientTransport, err e
|
|||
if connErr != nil {
|
||||
return nil, ConnectionErrorf("transport: %v", connErr)
|
||||
}
|
||||
// Perform handshake if opts.Handshaker is set.
|
||||
if opts.Handshaker != nil {
|
||||
auth, err := opts.Handshaker(conn)
|
||||
if err != nil {
|
||||
return nil, ConnectionErrorf("transport: handshaking failed %v", err)
|
||||
}
|
||||
// Prepend the resulting authenticator to opts.AuthOptions.
|
||||
if auth != nil {
|
||||
opts.AuthOptions = append([]credentials.Credentials{auth}, opts.AuthOptions...)
|
||||
}
|
||||
}
|
||||
for _, c := range opts.AuthOptions {
|
||||
if ccreds, ok := c.(credentials.TransportAuthenticator); ok {
|
||||
scheme = "https"
|
||||
|
|
|
@ -316,6 +316,7 @@ func NewServerTransport(protocol string, conn net.Conn, maxStreams uint32) (Serv
|
|||
// ConnectOptions covers all relevant options for dialing a server.
|
||||
type ConnectOptions struct {
|
||||
Dialer func(string, time.Duration) (net.Conn, error)
|
||||
Handshaker func(conn net.Conn) (credentials.TransportAuthenticator, error)
|
||||
AuthOptions []credentials.Credentials
|
||||
Timeout time.Duration
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче