github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/grpc/credentials/google/xds.go (about) 1 /* 2 * 3 * Copyright 2021 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 package google 20 21 import ( 22 "context" 23 "net" 24 "strings" 25 26 "github.com/hxx258456/ccgo/grpc/credentials" 27 "github.com/hxx258456/ccgo/grpc/internal" 28 ) 29 30 const cfeClusterNamePrefix = "google_cfe_" 31 32 // clusterTransportCreds is a combo of TLS + ALTS. 33 // 34 // On the client, ClientHandshake picks TLS or ALTS based on address attributes. 35 // - if attributes has cluster name 36 // - if cluster name has prefix "google_cfe_", use TLS 37 // - otherwise, use ALTS 38 // - else, do TLS 39 // 40 // On the server, ServerHandshake always does TLS. 41 type clusterTransportCreds struct { 42 tls credentials.TransportCredentials 43 alts credentials.TransportCredentials 44 } 45 46 func newClusterTransportCreds(tls, alts credentials.TransportCredentials) *clusterTransportCreds { 47 return &clusterTransportCreds{ 48 tls: tls, 49 alts: alts, 50 } 51 } 52 53 func (c *clusterTransportCreds) ClientHandshake(ctx context.Context, authority string, rawConn net.Conn) (net.Conn, credentials.AuthInfo, error) { 54 chi := credentials.ClientHandshakeInfoFromContext(ctx) 55 if chi.Attributes == nil { 56 return c.tls.ClientHandshake(ctx, authority, rawConn) 57 } 58 cn, ok := internal.GetXDSHandshakeClusterName(chi.Attributes) 59 if !ok || strings.HasPrefix(cn, cfeClusterNamePrefix) { 60 return c.tls.ClientHandshake(ctx, authority, rawConn) 61 } 62 // If attributes have cluster name, and cluster name is not cfe, it's a 63 // backend address, use ALTS. 64 return c.alts.ClientHandshake(ctx, authority, rawConn) 65 } 66 67 func (c *clusterTransportCreds) ServerHandshake(conn net.Conn) (net.Conn, credentials.AuthInfo, error) { 68 return c.tls.ServerHandshake(conn) 69 } 70 71 func (c *clusterTransportCreds) Info() credentials.ProtocolInfo { 72 // TODO: this always returns tls.Info now, because we don't have a cluster 73 // name to check when this method is called. This method doesn't affect 74 // anything important now. We may want to revisit this if it becomes more 75 // important later. 76 return c.tls.Info() 77 } 78 79 func (c *clusterTransportCreds) Clone() credentials.TransportCredentials { 80 return &clusterTransportCreds{ 81 tls: c.tls.Clone(), 82 alts: c.alts.Clone(), 83 } 84 } 85 86 func (c *clusterTransportCreds) OverrideServerName(s string) error { 87 if err := c.tls.OverrideServerName(s); err != nil { 88 return err 89 } 90 return c.alts.OverrideServerName(s) 91 }