From dd73d08e6a9928a599d2949b301c70787d119ec0 Mon Sep 17 00:00:00 2001 From: Gyuho Lee Date: Fri, 19 Jul 2019 08:35:58 -0700 Subject: [PATCH] clientv3/credentials: set dial target "Authority" with target address When user dials with "grpc.WithDialer", "grpc.DialContext" "cc.parsedTarget" update only happens once. This is problematic, because when TLS is enabled, retries happen through "grpc.WithDialer" with static "cc.parsedTarget" from the initial dial call. If the server authenticates by IP addresses, we want to set a new endpoint as a new authority. Otherwise "transport: authentication handshake failed: x509: certificate is valid for 127.0.0.1, 192.168.121.180, not 192.168.223.156" when the new dial target is "192.168.121.180" whose certificate host name is also "192.168.121.180" but client tries to authenticate with previously set "cc.parsedTarget" field "192.168.223.156" Signed-off-by: Gyuho Lee --- clientv3/credentials/credentials.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/clientv3/credentials/credentials.go b/clientv3/credentials/credentials.go index 500e6e5190ea..93f2f3762c10 100644 --- a/clientv3/credentials/credentials.go +++ b/clientv3/credentials/credentials.go @@ -71,6 +71,19 @@ func newTransportCredential(cfg *tls.Config) *transportCredential { } func (tc *transportCredential) ClientHandshake(ctx context.Context, authority string, rawConn net.Conn) (net.Conn, grpccredentials.AuthInfo, error) { + target := rawConn.RemoteAddr().String() + if authority != target { + // When user dials with "grpc.WithDialer", "grpc.DialContext" "cc.parsedTarget" + // update only happens once. This is problematic, because when TLS is enabled, + // retries happen through "grpc.WithDialer" with static "cc.parsedTarget" from + // the initial dial call. + // If the server authenticates by IP addresses, we want to set a new endpoint as + // a new authority. Otherwise + // "transport: authentication handshake failed: x509: certificate is valid for 127.0.0.1, 192.168.121.180, not 192.168.223.156" + // when the new dial target is "192.168.121.180" whose certificate host name is also "192.168.121.180" + // but client tries to authenticate with previously set "cc.parsedTarget" field "192.168.223.156" + authority = target + } return tc.gtc.ClientHandshake(ctx, authority, rawConn) }