clientconn: override authority with address's ServerName, if set (#3073)
This commit is contained in:
@ -1210,10 +1210,16 @@ func (ac *addrConn) createTransport(addr resolver.Address, copts transport.Conne
|
|||||||
onCloseCalled := make(chan struct{})
|
onCloseCalled := make(chan struct{})
|
||||||
reconnect := grpcsync.NewEvent()
|
reconnect := grpcsync.NewEvent()
|
||||||
|
|
||||||
|
authority := ac.cc.authority
|
||||||
|
// addr.ServerName takes precedent over ClientConn authority, if present.
|
||||||
|
if addr.ServerName != "" {
|
||||||
|
authority = addr.ServerName
|
||||||
|
}
|
||||||
|
|
||||||
target := transport.TargetInfo{
|
target := transport.TargetInfo{
|
||||||
Addr: addr.Addr,
|
Addr: addr.Addr,
|
||||||
Metadata: addr.Metadata,
|
Metadata: addr.Metadata,
|
||||||
Authority: ac.cc.authority,
|
Authority: authority,
|
||||||
}
|
}
|
||||||
|
|
||||||
once := sync.Once{}
|
once := sync.Once{}
|
||||||
|
@ -86,9 +86,16 @@ type Address struct {
|
|||||||
// Type is the type of this address.
|
// Type is the type of this address.
|
||||||
Type AddressType
|
Type AddressType
|
||||||
// ServerName is the name of this address.
|
// ServerName is the name of this address.
|
||||||
|
// If non-empty, the ServerName is used as the transport certification authority for
|
||||||
|
// the address, instead of the hostname from the Dial target string. In most cases,
|
||||||
|
// this should not be set.
|
||||||
//
|
//
|
||||||
// e.g. if Type is GRPCLB, ServerName should be the name of the remote load
|
// If Type is GRPCLB, ServerName should be the name of the remote load
|
||||||
// balancer, not the name of the backend.
|
// balancer, not the name of the backend.
|
||||||
|
//
|
||||||
|
// WARNING: ServerName must only be populated with trusted values. It
|
||||||
|
// is insecure to populate it with data from untrusted inputs since untrusted
|
||||||
|
// values could be used to bypass the authority checks performed by TLS.
|
||||||
ServerName string
|
ServerName string
|
||||||
// Metadata is the information associated with Addr, which may be used
|
// Metadata is the information associated with Addr, which may be used
|
||||||
// to make load balancing decision.
|
// to make load balancing decision.
|
||||||
|
@ -4969,6 +4969,49 @@ func (s) TestCredsHandshakeAuthority(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This test makes sure that the authority client handshake gets is the endpoint
|
||||||
|
// of the ServerName of the address when it is set.
|
||||||
|
func (s) TestCredsHandshakeServerNameAuthority(t *testing.T) {
|
||||||
|
const testAuthority = "test.auth.ori.ty"
|
||||||
|
const testServerName = "test.server.name"
|
||||||
|
|
||||||
|
lis, err := net.Listen("tcp", "localhost:0")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Failed to listen: %v", err)
|
||||||
|
}
|
||||||
|
cred := &authorityCheckCreds{}
|
||||||
|
s := grpc.NewServer()
|
||||||
|
go s.Serve(lis)
|
||||||
|
defer s.Stop()
|
||||||
|
|
||||||
|
r, rcleanup := manual.GenerateAndRegisterManualResolver()
|
||||||
|
defer rcleanup()
|
||||||
|
|
||||||
|
cc, err := grpc.Dial(r.Scheme()+":///"+testAuthority, grpc.WithTransportCredentials(cred))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("grpc.Dial(%q) = %v", lis.Addr().String(), err)
|
||||||
|
}
|
||||||
|
defer cc.Close()
|
||||||
|
r.UpdateState(resolver.State{Addresses: []resolver.Address{{Addr: lis.Addr().String(), ServerName: testServerName}}})
|
||||||
|
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
|
||||||
|
defer cancel()
|
||||||
|
for {
|
||||||
|
s := cc.GetState()
|
||||||
|
if s == connectivity.Ready {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if !cc.WaitForStateChange(ctx, s) {
|
||||||
|
// ctx got timeout or canceled.
|
||||||
|
t.Fatalf("ClientConn is not ready after 100 ms")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if cred.got != testServerName {
|
||||||
|
t.Fatalf("client creds got authority: %q, want: %q", cred.got, testAuthority)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type clientFailCreds struct{}
|
type clientFailCreds struct{}
|
||||||
|
|
||||||
func (c *clientFailCreds) ServerHandshake(rawConn net.Conn) (net.Conn, credentials.AuthInfo, error) {
|
func (c *clientFailCreds) ServerHandshake(rawConn net.Conn) (net.Conn, credentials.AuthInfo, error) {
|
||||||
|
Reference in New Issue
Block a user