浏览代码

bump google.golang.org/api v0.8.0

full diff: https://github.com/googleapis/google-api-go-client/compare/de943baf05a022a8f921b544b7827bacaba1aed5...v0.8.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Sebastiaan van Stijn 5 年之前
父节点
当前提交
a3256d2dd8
共有 47 个文件被更改,包括 6105 次插入162 次删除
  1. 1 1
      vendor.conf
  2. 3 3
      vendor/google.golang.org/api/README.md
  3. 23 0
      vendor/google.golang.org/api/go.mod
  4. 66 6
      vendor/google.golang.org/api/internal/creds.go
  5. 4 2
      vendor/google.golang.org/api/internal/pool.go
  6. 37 3
      vendor/google.golang.org/api/internal/settings.go
  7. 1 1
      vendor/google.golang.org/api/iterator/iterator.go
  8. 2 1
      vendor/google.golang.org/api/option/credentials_go19.go
  9. 1 1
      vendor/google.golang.org/api/option/credentials_notgo19.go
  10. 64 4
      vendor/google.golang.org/api/option/option.go
  11. 2 2
      vendor/google.golang.org/api/support/bundler/bundler.go
  12. 2 5
      vendor/google.golang.org/api/transport/dial.go
  13. 8 13
      vendor/google.golang.org/api/transport/doc.go
  14. 3 2
      vendor/google.golang.org/api/transport/go19.go
  15. 128 6
      vendor/google.golang.org/api/transport/grpc/dial.go
  16. 2 2
      vendor/google.golang.org/api/transport/grpc/dial_appengine.go
  17. 59 0
      vendor/google.golang.org/api/transport/grpc/dial_socketopt.go
  18. 0 21
      vendor/google.golang.org/api/transport/grpc/not_go18.go
  19. 81 29
      vendor/google.golang.org/api/transport/http/dial.go
  20. 2 2
      vendor/google.golang.org/api/transport/http/dial_appengine.go
  21. 0 31
      vendor/google.golang.org/api/transport/http/go18.go
  22. 6 4
      vendor/google.golang.org/api/transport/http/internal/propagation/http.go
  23. 0 21
      vendor/google.golang.org/api/transport/http/not_go18.go
  24. 3 2
      vendor/google.golang.org/api/transport/not_go19.go
  25. 772 0
      vendor/google.golang.org/grpc/balancer/grpclb/grpc_lb_v1/load_balancer.pb.go
  26. 488 0
      vendor/google.golang.org/grpc/balancer/grpclb/grpclb.go
  27. 66 0
      vendor/google.golang.org/grpc/balancer/grpclb/grpclb_config.go
  28. 202 0
      vendor/google.golang.org/grpc/balancer/grpclb/grpclb_picker.go
  29. 407 0
      vendor/google.golang.org/grpc/balancer/grpclb/grpclb_remote_balancer.go
  30. 208 0
      vendor/google.golang.org/grpc/balancer/grpclb/grpclb_util.go
  31. 330 0
      vendor/google.golang.org/grpc/credentials/alts/alts.go
  32. 89 0
      vendor/google.golang.org/grpc/credentials/alts/internal/authinfo/authinfo.go
  33. 69 0
      vendor/google.golang.org/grpc/credentials/alts/internal/common.go
  34. 131 0
      vendor/google.golang.org/grpc/credentials/alts/internal/conn/aeadrekey.go
  35. 105 0
      vendor/google.golang.org/grpc/credentials/alts/internal/conn/aes128gcm.go
  36. 116 0
      vendor/google.golang.org/grpc/credentials/alts/internal/conn/aes128gcmrekey.go
  37. 70 0
      vendor/google.golang.org/grpc/credentials/alts/internal/conn/common.go
  38. 62 0
      vendor/google.golang.org/grpc/credentials/alts/internal/conn/counter.go
  39. 271 0
      vendor/google.golang.org/grpc/credentials/alts/internal/conn/record.go
  40. 63 0
      vendor/google.golang.org/grpc/credentials/alts/internal/conn/utils.go
  41. 375 0
      vendor/google.golang.org/grpc/credentials/alts/internal/handshaker/handshaker.go
  42. 54 0
      vendor/google.golang.org/grpc/credentials/alts/internal/handshaker/service/service.go
  43. 152 0
      vendor/google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp/altscontext.pb.go
  44. 1105 0
      vendor/google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp/handshaker.pb.go
  45. 184 0
      vendor/google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp/transport_security_common.pb.go
  46. 163 0
      vendor/google.golang.org/grpc/credentials/alts/utils.go
  47. 125 0
      vendor/google.golang.org/grpc/credentials/google/google.go

+ 1 - 1
vendor.conf

@@ -116,7 +116,7 @@ github.com/bsphere/le_go                            7a984a84b5492ae539b79b62fb4a
 
 # gcplogs deps
 golang.org/x/oauth2                                 bf48bf16ab8d622ce64ec6ce98d2c98f916b6303
-google.golang.org/api                               de943baf05a022a8f921b544b7827bacaba1aed5
+google.golang.org/api                               dec2ee309f5b09fc59bc40676447c15736284d78 # v0.8.0
 github.com/golang/groupcache                        869f871628b6baa9cfbc11732cdf6546b17c1298
 go.opencensus.io                                    d835ff86be02193d324330acdb7d65546b05f814 # v0.22.3
 cloud.google.com/go                                 ceeb313ad77b789a7fa5287b36a1d127b69b7093 # v0.44.3

+ 3 - 3
vendor/google.golang.org/api/README.md

@@ -29,9 +29,9 @@ func main() {
 * For a longer tutorial, see the [Getting Started guide](https://github.com/google/google-api-go-client/blob/master/GettingStarted.md).
 * For examples, see the [examples directory](https://github.com/google/google-api-go-client/tree/master/examples).
 * For support, use the [golang-nuts](https://groups.google.com/group/golang-nuts) mailing list.
+* The code review instance may be found [here](https://code-review.googlesource.com).
 
 ## Status
-[![Build Status](https://travis-ci.org/google/google-api-go-client.png)](https://travis-ci.org/google/google-api-go-client)
 [![GoDoc](https://godoc.org/google.golang.org/api?status.svg)](https://godoc.org/google.golang.org/api)
 
 These are auto-generated Go libraries from the Google Discovery Service's JSON description files of the available "new style" Google APIs.
@@ -43,7 +43,7 @@ These client libraries are officially supported by Google.  However, the librari
 
 If you're working with Google Cloud Platform APIs such as Datastore or Pub/Sub,
 consider using the
-[Cloud Client Libraries for Go](https://github.com/GoogleCloudPlatform/google-cloud-go)
+[Cloud Client Libraries for Go](https://github.com/googleapis/google-cloud-go)
 instead. These are the new and
 idiomatic Go libraries targeted specifically at Google Cloud Platform Services.
 
@@ -71,7 +71,7 @@ Some credentials types require you to specify scopes, and service entry points m
 
 ```go
 import (
-        "golang.org/x/net/context"
+        "context"
         "golang.org/x/oauth2/google"
         "google.golang.org/api/compute/v1"
 )

+ 23 - 0
vendor/google.golang.org/api/go.mod

@@ -0,0 +1,23 @@
+module google.golang.org/api
+
+go 1.9
+
+require (
+	cloud.google.com/go v0.38.0 // indirect
+	github.com/golang/protobuf v1.3.1 // indirect
+	github.com/google/go-cmp v0.3.0
+	github.com/googleapis/gax-go/v2 v2.0.5
+	github.com/hashicorp/golang-lru v0.5.1 // indirect
+	go.opencensus.io v0.21.0
+	golang.org/x/lint v0.0.0-20190409202823-959b441ac422
+	golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c // indirect
+	golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
+	golang.org/x/sync v0.0.0-20190423024810-112230192c58
+	golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b
+	golang.org/x/text v0.3.2 // indirect
+	golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c
+	google.golang.org/appengine v1.5.0
+	google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873
+	google.golang.org/grpc v1.20.1
+	honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a
+)

+ 66 - 6
vendor/google.golang.org/api/internal/creds.go

@@ -1,4 +1,4 @@
-// Copyright 2017 Google Inc. All Rights Reserved.
+// Copyright 2017 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -15,28 +15,88 @@
 package internal
 
 import (
+	"context"
+	"encoding/json"
 	"fmt"
 	"io/ioutil"
 
-	"golang.org/x/net/context"
+	"golang.org/x/oauth2"
+
 	"golang.org/x/oauth2/google"
 )
 
 // Creds returns credential information obtained from DialSettings, or if none, then
 // it returns default credential information.
-func Creds(ctx context.Context, ds *DialSettings) (*google.DefaultCredentials, error) {
+func Creds(ctx context.Context, ds *DialSettings) (*google.Credentials, error) {
 	if ds.Credentials != nil {
 		return ds.Credentials, nil
 	}
+	if ds.CredentialsJSON != nil {
+		return credentialsFromJSON(ctx, ds.CredentialsJSON, ds.Endpoint, ds.Scopes, ds.Audiences)
+	}
 	if ds.CredentialsFile != "" {
 		data, err := ioutil.ReadFile(ds.CredentialsFile)
 		if err != nil {
 			return nil, fmt.Errorf("cannot read credentials file: %v", err)
 		}
-		return google.CredentialsFromJSON(ctx, data, ds.Scopes...)
+		return credentialsFromJSON(ctx, data, ds.Endpoint, ds.Scopes, ds.Audiences)
 	}
 	if ds.TokenSource != nil {
-		return &google.DefaultCredentials{TokenSource: ds.TokenSource}, nil
+		return &google.Credentials{TokenSource: ds.TokenSource}, nil
+	}
+	cred, err := google.FindDefaultCredentials(ctx, ds.Scopes...)
+	if err != nil {
+		return nil, err
+	}
+	if len(cred.JSON) > 0 {
+		return credentialsFromJSON(ctx, cred.JSON, ds.Endpoint, ds.Scopes, ds.Audiences)
+	}
+	// For GAE and GCE, the JSON is empty so return the default credentials directly.
+	return cred, nil
+}
+
+// JSON key file type.
+const (
+	serviceAccountKey = "service_account"
+)
+
+// credentialsFromJSON returns a google.Credentials based on the input.
+//
+// - If the JSON is a service account and no scopes provided, returns self-signed JWT auth flow
+// - Otherwise, returns OAuth 2.0 flow.
+func credentialsFromJSON(ctx context.Context, data []byte, endpoint string, scopes []string, audiences []string) (*google.Credentials, error) {
+	cred, err := google.CredentialsFromJSON(ctx, data, scopes...)
+	if err != nil {
+		return nil, err
+	}
+	if len(data) > 0 && len(scopes) == 0 {
+		var f struct {
+			Type string `json:"type"`
+			// The rest JSON fields are omitted because they are not used.
+		}
+		if err := json.Unmarshal(cred.JSON, &f); err != nil {
+			return nil, err
+		}
+		if f.Type == serviceAccountKey {
+			ts, err := selfSignedJWTTokenSource(data, endpoint, audiences)
+			if err != nil {
+				return nil, err
+			}
+			cred.TokenSource = ts
+		}
+	}
+	return cred, err
+}
+
+func selfSignedJWTTokenSource(data []byte, endpoint string, audiences []string) (oauth2.TokenSource, error) {
+	// Use the API endpoint as the default audience
+	audience := endpoint
+	if len(audiences) > 0 {
+		// TODO(shinfan): Update golang oauth to support multiple audiences.
+		if len(audiences) > 1 {
+			return nil, fmt.Errorf("multiple audiences support is not implemented")
+		}
+		audience = audiences[0]
 	}
-	return google.FindDefaultCredentials(ctx, ds.Scopes...)
+	return google.JWTAccessTokenSourceFromJSON(data, audience)
 }

+ 4 - 2
vendor/google.golang.org/api/internal/pool.go

@@ -1,4 +1,4 @@
-// Copyright 2016 Google Inc. All Rights Reserved.
+// Copyright 2016 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@ package internal
 
 import (
 	"errors"
+
 	"google.golang.org/grpc/naming"
 )
 
@@ -37,7 +38,7 @@ func NewPoolResolver(size int, o *DialSettings) *PoolResolver {
 // provided to NewPoolResolver.
 func (r *PoolResolver) Resolve(target string) (naming.Watcher, error) {
 	if r.dialOpt.Endpoint == "" {
-		return nil, errors.New("No endpoint configured")
+		return nil, errors.New("no endpoint configured")
 	}
 	addrs := make([]*naming.Update, 0, r.poolSize)
 	for i := 0; i < r.poolSize; i++ {
@@ -54,6 +55,7 @@ func (r *PoolResolver) Next() ([]*naming.Update, error) {
 	return <-r.ch, nil
 }
 
+// Close releases resources associated with the pool and causes Next to unblock.
 func (r *PoolResolver) Close() {
 	close(r.ch)
 }

+ 37 - 3
vendor/google.golang.org/api/internal/settings.go

@@ -1,4 +1,4 @@
-// Copyright 2017 Google Inc. All Rights Reserved.
+// Copyright 2017 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -30,14 +30,21 @@ type DialSettings struct {
 	Endpoint        string
 	Scopes          []string
 	TokenSource     oauth2.TokenSource
-	Credentials     *google.DefaultCredentials
+	Credentials     *google.Credentials
 	CredentialsFile string // if set, Token Source is ignored.
+	CredentialsJSON []byte
 	UserAgent       string
 	APIKey          string
+	Audiences       []string
 	HTTPClient      *http.Client
 	GRPCDialOpts    []grpc.DialOption
 	GRPCConn        *grpc.ClientConn
 	NoAuth          bool
+
+	// Google API system parameters. For more information please read:
+	// https://cloud.google.com/apis/docs/system-parameters
+	QuotaProject  string
+	RequestReason string
 }
 
 // Validate reports an error if ds is invalid.
@@ -49,7 +56,27 @@ func (ds *DialSettings) Validate() error {
 	// Credentials should not appear with other options.
 	// We currently allow TokenSource and CredentialsFile to coexist.
 	// TODO(jba): make TokenSource & CredentialsFile an error (breaking change).
-	if ds.Credentials != nil && (ds.APIKey != "" || ds.TokenSource != nil || ds.CredentialsFile != "") {
+	nCreds := 0
+	if ds.Credentials != nil {
+		nCreds++
+	}
+	if ds.CredentialsJSON != nil {
+		nCreds++
+	}
+	if ds.CredentialsFile != "" {
+		nCreds++
+	}
+	if ds.APIKey != "" {
+		nCreds++
+	}
+	if ds.TokenSource != nil {
+		nCreds++
+	}
+	if len(ds.Scopes) > 0 && len(ds.Audiences) > 0 {
+		return errors.New("WithScopes is incompatible with WithAudience")
+	}
+	// Accept only one form of credentials, except we allow TokenSource and CredentialsFile for backwards compatibility.
+	if nCreds > 1 && !(nCreds == 2 && ds.TokenSource != nil && ds.CredentialsFile != "") {
 		return errors.New("multiple credential options provided")
 	}
 	if ds.HTTPClient != nil && ds.GRPCConn != nil {
@@ -58,5 +85,12 @@ func (ds *DialSettings) Validate() error {
 	if ds.HTTPClient != nil && ds.GRPCDialOpts != nil {
 		return errors.New("WithHTTPClient is incompatible with gRPC dial options")
 	}
+	if ds.HTTPClient != nil && ds.QuotaProject != "" {
+		return errors.New("WithHTTPClient is incompatible with QuotaProject")
+	}
+	if ds.HTTPClient != nil && ds.RequestReason != "" {
+		return errors.New("WithHTTPClient is incompatible with RequestReason")
+	}
+
 	return nil
 }

+ 1 - 1
vendor/google.golang.org/api/iterator/iterator.go

@@ -1,4 +1,4 @@
-// Copyright 2016 Google Inc. All Rights Reserved.
+// Copyright 2016 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.

+ 2 - 1
vendor/google.golang.org/api/option/credentials_go19.go

@@ -1,4 +1,4 @@
-// Copyright 2018 Google Inc. All Rights Reserved.
+// Copyright 2018 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -27,6 +27,7 @@ func (w *withCreds) Apply(o *internal.DialSettings) {
 	o.Credentials = (*google.Credentials)(w)
 }
 
+// WithCredentials returns a ClientOption that authenticates API calls.
 func WithCredentials(creds *google.Credentials) ClientOption {
 	return (*withCreds)(creds)
 }

+ 1 - 1
vendor/google.golang.org/api/option/credentials_notgo19.go

@@ -1,4 +1,4 @@
-// Copyright 2018 Google Inc. All Rights Reserved.
+// Copyright 2018 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.

+ 64 - 4
vendor/google.golang.org/api/option/option.go

@@ -1,4 +1,4 @@
-// Copyright 2017 Google Inc. All Rights Reserved.
+// Copyright 2017 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -61,6 +61,20 @@ func WithServiceAccountFile(filename string) ClientOption {
 	return WithCredentialsFile(filename)
 }
 
+// WithCredentialsJSON returns a ClientOption that authenticates
+// API calls with the given service account or refresh token JSON
+// credentials.
+func WithCredentialsJSON(p []byte) ClientOption {
+	return withCredentialsJSON(p)
+}
+
+type withCredentialsJSON []byte
+
+func (w withCredentialsJSON) Apply(o *internal.DialSettings) {
+	o.CredentialsJSON = make([]byte, len(w))
+	copy(o.CredentialsJSON, w)
+}
+
 // WithEndpoint returns a ClientOption that overrides the default endpoint
 // to be used for a service.
 func WithEndpoint(url string) ClientOption {
@@ -82,9 +96,8 @@ func WithScopes(scope ...string) ClientOption {
 type withScopes []string
 
 func (w withScopes) Apply(o *internal.DialSettings) {
-	s := make([]string, len(w))
-	copy(s, w)
-	o.Scopes = s
+	o.Scopes = make([]string, len(w))
+	copy(o.Scopes, w)
 }
 
 // WithUserAgent returns a ClientOption that sets the User-Agent.
@@ -153,6 +166,9 @@ func (w withGRPCConnectionPool) Apply(o *internal.DialSettings) {
 
 // WithAPIKey returns a ClientOption that specifies an API key to be used
 // as the basis for authentication.
+//
+// API Keys can only be used for JSON-over-HTTP APIs, including those under
+// the import path google.golang.org/api/....
 func WithAPIKey(apiKey string) ClientOption {
 	return withAPIKey(apiKey)
 }
@@ -161,6 +177,19 @@ type withAPIKey string
 
 func (w withAPIKey) Apply(o *internal.DialSettings) { o.APIKey = string(w) }
 
+// WithAudiences returns a ClientOption that specifies an audience to be used
+// as the audience field ("aud") for the JWT token authentication.
+func WithAudiences(audience ...string) ClientOption {
+	return withAudiences(audience)
+}
+
+type withAudiences []string
+
+func (w withAudiences) Apply(o *internal.DialSettings) {
+	o.Audiences = make([]string, len(w))
+	copy(o.Audiences, w)
+}
+
 // WithoutAuthentication returns a ClientOption that specifies that no
 // authentication should be used. It is suitable only for testing and for
 // accessing public resources, like public Google Cloud Storage buckets.
@@ -173,3 +202,34 @@ func WithoutAuthentication() ClientOption {
 type withoutAuthentication struct{}
 
 func (w withoutAuthentication) Apply(o *internal.DialSettings) { o.NoAuth = true }
+
+// WithQuotaProject returns a ClientOption that specifies the project used
+// for quota and billing purposes.
+//
+// For more information please read:
+// https://cloud.google.com/apis/docs/system-parameters
+func WithQuotaProject(quotaProject string) ClientOption {
+	return withQuotaProject(quotaProject)
+}
+
+type withQuotaProject string
+
+func (w withQuotaProject) Apply(o *internal.DialSettings) {
+	o.QuotaProject = string(w)
+}
+
+// WithRequestReason returns a ClientOption that specifies a reason for
+// making the request, which is intended to be recorded in audit logging.
+// An example reason would be a support-case ticket number.
+//
+// For more information please read:
+// https://cloud.google.com/apis/docs/system-parameters
+func WithRequestReason(requestReason string) ClientOption {
+	return withRequestReason(requestReason)
+}
+
+type withRequestReason string
+
+func (w withRequestReason) Apply(o *internal.DialSettings) {
+	o.RequestReason = string(w)
+}

+ 2 - 2
vendor/google.golang.org/api/support/bundler/bundler.go

@@ -1,4 +1,4 @@
-// Copyright 2016 Google Inc. All Rights Reserved.
+// Copyright 2016 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -22,13 +22,13 @@
 package bundler
 
 import (
+	"context"
 	"errors"
 	"math"
 	"reflect"
 	"sync"
 	"time"
 
-	"golang.org/x/net/context"
 	"golang.org/x/sync/semaphore"
 )
 

+ 2 - 5
vendor/google.golang.org/api/transport/dial.go

@@ -1,4 +1,4 @@
-// Copyright 2015 Google Inc. All Rights Reserved.
+// Copyright 2015 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -12,15 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-// Package transport supports network connections to HTTP and GRPC servers.
-// This package is not intended for use by end developers. Use the
-// google.golang.org/api/option package to configure API clients.
 package transport
 
 import (
+	"context"
 	"net/http"
 
-	"golang.org/x/net/context"
 	"google.golang.org/grpc"
 
 	"google.golang.org/api/option"

+ 8 - 13
vendor/google.golang.org/api/transport/grpc/go18.go → vendor/google.golang.org/api/transport/doc.go

@@ -1,4 +1,4 @@
-// Copyright 2018 Google Inc. All Rights Reserved.
+// Copyright 2019 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -12,15 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-// +build go1.8
-
-package grpc
-
-import (
-	"go.opencensus.io/plugin/ocgrpc"
-	"google.golang.org/grpc"
-)
-
-func addOCStatsHandler(opts []grpc.DialOption) []grpc.DialOption {
-	return append(opts, grpc.WithStatsHandler(&ocgrpc.ClientHandler{}))
-}
+// Package transport provides utility methods for creating authenticated
+// transports to Google's HTTP and gRPC APIs. It is intended to be used in
+// conjunction with google.golang.org/api/option.
+//
+// This package is not intended for use by end developers. Use the
+// google.golang.org/api/option package to configure API clients.
+package transport

+ 3 - 2
vendor/google.golang.org/api/transport/go19.go

@@ -1,4 +1,4 @@
-// Copyright 2018 Google Inc. All Rights Reserved.
+// Copyright 2018 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -17,7 +17,8 @@
 package transport
 
 import (
-	"golang.org/x/net/context"
+	"context"
+
 	"golang.org/x/oauth2/google"
 	"google.golang.org/api/internal"
 	"google.golang.org/api/option"

+ 128 - 6
vendor/google.golang.org/api/transport/grpc/dial.go

@@ -1,4 +1,4 @@
-// Copyright 2015 Google Inc. All Rights Reserved.
+// Copyright 2015 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -12,25 +12,37 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-// Package transport/grpc supports network connections to GRPC servers.
+// Package grpc supports network connections to GRPC servers.
 // This package is not intended for use by end developers. Use the
 // google.golang.org/api/option package to configure API clients.
 package grpc
 
 import (
+	"context"
 	"errors"
+	"log"
+	"os"
+	"strings"
 
-	"golang.org/x/net/context"
+	"go.opencensus.io/plugin/ocgrpc"
+	"golang.org/x/oauth2"
 	"google.golang.org/api/internal"
 	"google.golang.org/api/option"
 	"google.golang.org/grpc"
 	"google.golang.org/grpc/credentials"
+	grpcgoogle "google.golang.org/grpc/credentials/google"
 	"google.golang.org/grpc/credentials/oauth"
+
+	// Install grpclb, which is required for direct path.
+	_ "google.golang.org/grpc/balancer/grpclb"
 )
 
 // Set at init time by dial_appengine.go. If nil, we're not on App Engine.
 var appengineDialerHook func(context.Context) grpc.DialOption
 
+// Set at init time by dial_socketopt.go. If nil, socketopt is not supported.
+var timeoutDialerOption grpc.DialOption
+
 // Dial returns a GRPC connection for use communicating with a Google cloud
 // service, configured with the given ClientOptions.
 func Dial(ctx context.Context, opts ...option.ClientOption) (*grpc.ClientConn, error) {
@@ -62,19 +74,47 @@ func dial(ctx context.Context, insecure bool, opts []option.ClientOption) (*grpc
 	if insecure {
 		grpcOpts = []grpc.DialOption{grpc.WithInsecure()}
 	} else if !o.NoAuth {
+		if o.APIKey != "" {
+			log.Print("API keys are not supported for gRPC APIs. Remove the WithAPIKey option from your client-creating call.")
+		}
 		creds, err := internal.Creds(ctx, &o)
 		if err != nil {
 			return nil, err
 		}
-		grpcOpts = []grpc.DialOption{
-			grpc.WithPerRPCCredentials(oauth.TokenSource{creds.TokenSource}),
-			grpc.WithTransportCredentials(credentials.NewClientTLSFromCert(nil, "")),
+		// Attempt Direct Path only if:
+		// * The endpoint is a host:port (or dns:///host:port).
+		// * Credentials are obtained via GCE metadata server, using the default
+		//   service account.
+		// * Opted in via GOOGLE_CLOUD_ENABLE_DIRECT_PATH environment variable.
+		//   For example, GOOGLE_CLOUD_ENABLE_DIRECT_PATH=spanner,pubsub
+		if isDirectPathEnabled(o.Endpoint) && isTokenSourceDirectPathCompatible(creds.TokenSource) {
+			if !strings.HasPrefix(o.Endpoint, "dns:///") {
+				o.Endpoint = "dns:///" + o.Endpoint
+			}
+			grpcOpts = []grpc.DialOption{
+				grpc.WithCredentialsBundle(
+					grpcgoogle.NewComputeEngineCredentials(),
+				),
+			}
+			// TODO(cbro): add support for system parameters (quota project, request reason) via chained interceptor.
+		} else {
+			grpcOpts = []grpc.DialOption{
+				grpc.WithPerRPCCredentials(grpcTokenSource{
+					TokenSource:   oauth.TokenSource{creds.TokenSource},
+					quotaProject:  o.QuotaProject,
+					requestReason: o.RequestReason,
+				}),
+				grpc.WithTransportCredentials(credentials.NewClientTLSFromCert(nil, "")),
+			}
 		}
 	}
+
 	if appengineDialerHook != nil {
 		// Use the Socket API on App Engine.
+		// appengine dialer will override socketopt dialer
 		grpcOpts = append(grpcOpts, appengineDialerHook(ctx))
 	}
+
 	// Add tracing, but before the other options, so that clients can override the
 	// gRPC stats handler.
 	// This assumes that gRPC options are processed in order, left to right.
@@ -83,5 +123,87 @@ func dial(ctx context.Context, insecure bool, opts []option.ClientOption) (*grpc
 	if o.UserAgent != "" {
 		grpcOpts = append(grpcOpts, grpc.WithUserAgent(o.UserAgent))
 	}
+
+	// TODO(weiranf): This socketopt dialer will be used by default at some
+	// point when isDirectPathEnabled will default to true, we guard it by
+	// the Directpath env var for now once we can introspect user defined
+	// dialer (https://github.com/grpc/grpc-go/issues/2795).
+	if timeoutDialerOption != nil && isDirectPathEnabled(o.Endpoint) {
+		grpcOpts = append(grpcOpts, timeoutDialerOption)
+	}
+
 	return grpc.DialContext(ctx, o.Endpoint, grpcOpts...)
 }
+
+func addOCStatsHandler(opts []grpc.DialOption) []grpc.DialOption {
+	return append(opts, grpc.WithStatsHandler(&ocgrpc.ClientHandler{}))
+}
+
+// grpcTokenSource supplies PerRPCCredentials from an oauth.TokenSource.
+type grpcTokenSource struct {
+	oauth.TokenSource
+
+	// Additional metadata attached as headers.
+	quotaProject  string
+	requestReason string
+}
+
+// GetRequestMetadata gets the request metadata as a map from a grpcTokenSource.
+func (ts grpcTokenSource) GetRequestMetadata(ctx context.Context, uri ...string) (
+	map[string]string, error) {
+	metadata, err := ts.TokenSource.GetRequestMetadata(ctx, uri...)
+	if err != nil {
+		return nil, err
+	}
+
+	// Attach system parameter
+	if ts.quotaProject != "" {
+		metadata["X-goog-user-project"] = ts.quotaProject
+	}
+	if ts.requestReason != "" {
+		metadata["X-goog-request-reason"] = ts.requestReason
+	}
+	return metadata, nil
+}
+
+func isTokenSourceDirectPathCompatible(ts oauth2.TokenSource) bool {
+	if ts == nil {
+		return false
+	}
+	tok, err := ts.Token()
+	if err != nil {
+		return false
+	}
+	if tok == nil {
+		return false
+	}
+	if source, _ := tok.Extra("oauth2.google.tokenSource").(string); source != "compute-metadata" {
+		return false
+	}
+	if acct, _ := tok.Extra("oauth2.google.serviceAccount").(string); acct != "default" {
+		return false
+	}
+	return true
+}
+
+func isDirectPathEnabled(endpoint string) bool {
+	// Only host:port is supported, not other schemes (e.g., "tcp://" or "unix://").
+	// Also don't try direct path if the user has chosen an alternate name resolver
+	// (i.e., via ":///" prefix).
+	//
+	// TODO(cbro): once gRPC has introspectible options, check the user hasn't
+	// provided a custom dialer in gRPC options.
+	if strings.Contains(endpoint, "://") && !strings.HasPrefix(endpoint, "dns:///") {
+		return false
+	}
+
+	// Only try direct path if the user has opted in via the environment variable.
+	whitelist := strings.Split(os.Getenv("GOOGLE_CLOUD_ENABLE_DIRECT_PATH"), ",")
+	for _, api := range whitelist {
+		// Ignore empty string since an empty env variable splits into [""]
+		if api != "" && strings.Contains(endpoint, api) {
+			return true
+		}
+	}
+	return false
+}

+ 2 - 2
vendor/google.golang.org/api/transport/grpc/dial_appengine.go

@@ -1,4 +1,4 @@
-// Copyright 2016 Google Inc. All Rights Reserved.
+// Copyright 2016 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -17,10 +17,10 @@
 package grpc
 
 import (
+	"context"
 	"net"
 	"time"
 
-	"golang.org/x/net/context"
 	"google.golang.org/appengine"
 	"google.golang.org/appengine/socket"
 	"google.golang.org/grpc"

+ 59 - 0
vendor/google.golang.org/api/transport/grpc/dial_socketopt.go

@@ -0,0 +1,59 @@
+// Copyright 2019 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// +build go1.11,linux
+
+package grpc
+
+import (
+	"context"
+	"net"
+	"syscall"
+
+	"golang.org/x/sys/unix"
+	"google.golang.org/grpc"
+)
+
+const (
+	// defaultTCPUserTimeout is the default TCP_USER_TIMEOUT socket option. By
+	// default is 20 seconds.
+	tcpUserTimeoutMilliseconds = 20000
+)
+
+func init() {
+	// timeoutDialerOption is a grpc.DialOption that contains dialer with
+	// socket option TCP_USER_TIMEOUT. This dialer requires go versions 1.11+.
+	timeoutDialerOption = grpc.WithContextDialer(dialTCPUserTimeout)
+}
+
+func dialTCPUserTimeout(ctx context.Context, addr string) (net.Conn, error) {
+	control := func(network, address string, c syscall.RawConn) error {
+		var syscallErr error
+		controlErr := c.Control(func(fd uintptr) {
+			syscallErr = syscall.SetsockoptInt(
+				int(fd), syscall.IPPROTO_TCP, unix.TCP_USER_TIMEOUT, tcpUserTimeoutMilliseconds)
+		})
+		if syscallErr != nil {
+			return syscallErr
+		}
+		if controlErr != nil {
+			return controlErr
+		}
+		return nil
+	}
+	d := &net.Dialer{
+		Control: control,
+	}
+	return d.DialContext(ctx, "tcp", addr)
+}

+ 0 - 21
vendor/google.golang.org/api/transport/grpc/not_go18.go

@@ -1,21 +0,0 @@
-// Copyright 2018 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// +build !go1.8
-
-package grpc
-
-import "google.golang.org/grpc"
-
-func addOCStatsHandler(opts []grpc.DialOption) []grpc.DialOption { return opts }

+ 81 - 29
vendor/google.golang.org/api/transport/http/dial.go

@@ -1,4 +1,4 @@
-// Copyright 2015 Google Inc. All Rights Reserved.
+// Copyright 2015 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -12,73 +12,109 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-// Package transport/http supports network connections to HTTP servers.
+// Package http supports network connections to HTTP servers.
 // This package is not intended for use by end developers. Use the
 // google.golang.org/api/option package to configure API clients.
 package http
 
 import (
+	"context"
 	"errors"
 	"net/http"
 
-	"golang.org/x/net/context"
+	"go.opencensus.io/plugin/ochttp"
 	"golang.org/x/oauth2"
 	"google.golang.org/api/googleapi/transport"
 	"google.golang.org/api/internal"
 	"google.golang.org/api/option"
+	"google.golang.org/api/transport/http/internal/propagation"
 )
 
 // NewClient returns an HTTP client for use communicating with a Google cloud
 // service, configured with the given ClientOptions. It also returns the endpoint
 // for the service as specified in the options.
 func NewClient(ctx context.Context, opts ...option.ClientOption) (*http.Client, string, error) {
-	var o internal.DialSettings
-	for _, opt := range opts {
-		opt.Apply(&o)
+	settings, err := newSettings(opts)
+	if err != nil {
+		return nil, "", err
 	}
-	if err := o.Validate(); err != nil {
+	// TODO(cbro): consider injecting the User-Agent even if an explicit HTTP client is provided?
+	if settings.HTTPClient != nil {
+		return settings.HTTPClient, settings.Endpoint, nil
+	}
+	trans, err := newTransport(ctx, defaultBaseTransport(ctx), settings)
+	if err != nil {
 		return nil, "", err
 	}
-	if o.GRPCConn != nil {
-		return nil, "", errors.New("unsupported gRPC connection specified")
+	return &http.Client{Transport: trans}, settings.Endpoint, nil
+}
+
+// NewTransport creates an http.RoundTripper for use communicating with a Google
+// cloud service, configured with the given ClientOptions. Its RoundTrip method delegates to base.
+func NewTransport(ctx context.Context, base http.RoundTripper, opts ...option.ClientOption) (http.RoundTripper, error) {
+	settings, err := newSettings(opts)
+	if err != nil {
+		return nil, err
 	}
-	// TODO(cbro): consider injecting the User-Agent even if an explicit HTTP client is provided?
-	if o.HTTPClient != nil {
-		return o.HTTPClient, o.Endpoint, nil
+	if settings.HTTPClient != nil {
+		return nil, errors.New("transport/http: WithHTTPClient passed to NewTransport")
 	}
-	trans := baseTransport(ctx)
-	trans = userAgentTransport{
-		base:      trans,
-		userAgent: o.UserAgent,
+	return newTransport(ctx, base, settings)
+}
+
+func newTransport(ctx context.Context, base http.RoundTripper, settings *internal.DialSettings) (http.RoundTripper, error) {
+	trans := base
+	trans = parameterTransport{
+		base:          trans,
+		userAgent:     settings.UserAgent,
+		quotaProject:  settings.QuotaProject,
+		requestReason: settings.RequestReason,
 	}
 	trans = addOCTransport(trans)
 	switch {
-	case o.NoAuth:
+	case settings.NoAuth:
 		// Do nothing.
-	case o.APIKey != "":
+	case settings.APIKey != "":
 		trans = &transport.APIKey{
 			Transport: trans,
-			Key:       o.APIKey,
+			Key:       settings.APIKey,
 		}
 	default:
-		creds, err := internal.Creds(ctx, &o)
+		creds, err := internal.Creds(ctx, settings)
 		if err != nil {
-			return nil, "", err
+			return nil, err
 		}
 		trans = &oauth2.Transport{
 			Base:   trans,
 			Source: creds.TokenSource,
 		}
 	}
-	return &http.Client{Transport: trans}, o.Endpoint, nil
+	return trans, nil
 }
 
-type userAgentTransport struct {
-	userAgent string
-	base      http.RoundTripper
+func newSettings(opts []option.ClientOption) (*internal.DialSettings, error) {
+	var o internal.DialSettings
+	for _, opt := range opts {
+		opt.Apply(&o)
+	}
+	if err := o.Validate(); err != nil {
+		return nil, err
+	}
+	if o.GRPCConn != nil {
+		return nil, errors.New("unsupported gRPC connection specified")
+	}
+	return &o, nil
+}
+
+type parameterTransport struct {
+	userAgent     string
+	quotaProject  string
+	requestReason string
+
+	base http.RoundTripper
 }
 
-func (t userAgentTransport) RoundTrip(req *http.Request) (*http.Response, error) {
+func (t parameterTransport) RoundTrip(req *http.Request) (*http.Response, error) {
 	rt := t.base
 	if rt == nil {
 		return nil, errors.New("transport: no Transport specified")
@@ -92,18 +128,34 @@ func (t userAgentTransport) RoundTrip(req *http.Request) (*http.Response, error)
 		newReq.Header[k] = vv
 	}
 	// TODO(cbro): append to existing User-Agent header?
-	newReq.Header["User-Agent"] = []string{t.userAgent}
+	newReq.Header.Set("User-Agent", t.userAgent)
+
+	// Attach system parameters into the header
+	if t.quotaProject != "" {
+		newReq.Header.Set("X-Goog-User-Project", t.quotaProject)
+	}
+	if t.requestReason != "" {
+		newReq.Header.Set("X-Goog-Request-Reason", t.requestReason)
+	}
+
 	return rt.RoundTrip(&newReq)
 }
 
 // Set at init time by dial_appengine.go. If nil, we're not on App Engine.
 var appengineUrlfetchHook func(context.Context) http.RoundTripper
 
-// baseTransport returns the base HTTP transport.
+// defaultBaseTransport returns the base HTTP transport.
 // On App Engine, this is urlfetch.Transport, otherwise it's http.DefaultTransport.
-func baseTransport(ctx context.Context) http.RoundTripper {
+func defaultBaseTransport(ctx context.Context) http.RoundTripper {
 	if appengineUrlfetchHook != nil {
 		return appengineUrlfetchHook(ctx)
 	}
 	return http.DefaultTransport
 }
+
+func addOCTransport(trans http.RoundTripper) http.RoundTripper {
+	return &ochttp.Transport{
+		Base:        trans,
+		Propagation: &propagation.HTTPFormat{},
+	}
+}

+ 2 - 2
vendor/google.golang.org/api/transport/http/dial_appengine.go

@@ -1,4 +1,4 @@
-// Copyright 2016 Google Inc. All Rights Reserved.
+// Copyright 2016 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -17,9 +17,9 @@
 package http
 
 import (
+	"context"
 	"net/http"
 
-	"golang.org/x/net/context"
 	"google.golang.org/appengine/urlfetch"
 )
 

+ 0 - 31
vendor/google.golang.org/api/transport/http/go18.go

@@ -1,31 +0,0 @@
-// Copyright 2018 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// +build go1.8
-
-package http
-
-import (
-	"net/http"
-
-	"go.opencensus.io/exporter/stackdriver/propagation"
-	"go.opencensus.io/plugin/ochttp"
-)
-
-func addOCTransport(trans http.RoundTripper) http.RoundTripper {
-	return &ochttp.Transport{
-		Base:        trans,
-		Propagation: &propagation.HTTPFormat{},
-	}
-}

+ 6 - 4
vendor/go.opencensus.io/exporter/stackdriver/propagation/http.go → vendor/google.golang.org/api/transport/http/internal/propagation/http.go

@@ -1,10 +1,10 @@
-// Copyright 2018, OpenCensus Authors
+// Copyright 2018 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
 // You may obtain a copy of the License at
 //
-//     http://www.apache.org/licenses/LICENSE-2.0
+//      http://www.apache.org/licenses/LICENSE-2.0
 //
 // Unless required by applicable law or agreed to in writing, software
 // distributed under the License is distributed on an "AS IS" BASIS,
@@ -12,9 +12,11 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-// Package propagation implement X-Cloud-Trace-Context header propagation used
+// +build go1.8
+
+// Package propagation implements X-Cloud-Trace-Context header propagation used
 // by Google Cloud products.
-package propagation // import "go.opencensus.io/exporter/stackdriver/propagation"
+package propagation
 
 import (
 	"encoding/binary"

+ 0 - 21
vendor/google.golang.org/api/transport/http/not_go18.go

@@ -1,21 +0,0 @@
-// Copyright 2018 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// +build !go1.8
-
-package http
-
-import "net/http"
-
-func addOCTransport(trans http.RoundTripper) http.RoundTripper { return trans }

+ 3 - 2
vendor/google.golang.org/api/transport/not_go19.go

@@ -1,4 +1,4 @@
-// Copyright 2018 Google Inc. All Rights Reserved.
+// Copyright 2018 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -17,7 +17,8 @@
 package transport
 
 import (
-	"golang.org/x/net/context"
+	"context"
+
 	"golang.org/x/oauth2/google"
 	"google.golang.org/api/internal"
 	"google.golang.org/api/option"

+ 772 - 0
vendor/google.golang.org/grpc/balancer/grpclb/grpc_lb_v1/load_balancer.pb.go

@@ -0,0 +1,772 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: grpc/lb/v1/load_balancer.proto
+
+package grpc_lb_v1
+
+import (
+	context "context"
+	fmt "fmt"
+	proto "github.com/golang/protobuf/proto"
+	duration "github.com/golang/protobuf/ptypes/duration"
+	timestamp "github.com/golang/protobuf/ptypes/timestamp"
+	grpc "google.golang.org/grpc"
+	codes "google.golang.org/grpc/codes"
+	status "google.golang.org/grpc/status"
+	math "math"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
+
+type LoadBalanceRequest struct {
+	// Types that are valid to be assigned to LoadBalanceRequestType:
+	//	*LoadBalanceRequest_InitialRequest
+	//	*LoadBalanceRequest_ClientStats
+	LoadBalanceRequestType isLoadBalanceRequest_LoadBalanceRequestType `protobuf_oneof:"load_balance_request_type"`
+	XXX_NoUnkeyedLiteral   struct{}                                    `json:"-"`
+	XXX_unrecognized       []byte                                      `json:"-"`
+	XXX_sizecache          int32                                       `json:"-"`
+}
+
+func (m *LoadBalanceRequest) Reset()         { *m = LoadBalanceRequest{} }
+func (m *LoadBalanceRequest) String() string { return proto.CompactTextString(m) }
+func (*LoadBalanceRequest) ProtoMessage()    {}
+func (*LoadBalanceRequest) Descriptor() ([]byte, []int) {
+	return fileDescriptor_7cd3f6d792743fdf, []int{0}
+}
+
+func (m *LoadBalanceRequest) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_LoadBalanceRequest.Unmarshal(m, b)
+}
+func (m *LoadBalanceRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_LoadBalanceRequest.Marshal(b, m, deterministic)
+}
+func (m *LoadBalanceRequest) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_LoadBalanceRequest.Merge(m, src)
+}
+func (m *LoadBalanceRequest) XXX_Size() int {
+	return xxx_messageInfo_LoadBalanceRequest.Size(m)
+}
+func (m *LoadBalanceRequest) XXX_DiscardUnknown() {
+	xxx_messageInfo_LoadBalanceRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_LoadBalanceRequest proto.InternalMessageInfo
+
+type isLoadBalanceRequest_LoadBalanceRequestType interface {
+	isLoadBalanceRequest_LoadBalanceRequestType()
+}
+
+type LoadBalanceRequest_InitialRequest struct {
+	InitialRequest *InitialLoadBalanceRequest `protobuf:"bytes,1,opt,name=initial_request,json=initialRequest,proto3,oneof"`
+}
+
+type LoadBalanceRequest_ClientStats struct {
+	ClientStats *ClientStats `protobuf:"bytes,2,opt,name=client_stats,json=clientStats,proto3,oneof"`
+}
+
+func (*LoadBalanceRequest_InitialRequest) isLoadBalanceRequest_LoadBalanceRequestType() {}
+
+func (*LoadBalanceRequest_ClientStats) isLoadBalanceRequest_LoadBalanceRequestType() {}
+
+func (m *LoadBalanceRequest) GetLoadBalanceRequestType() isLoadBalanceRequest_LoadBalanceRequestType {
+	if m != nil {
+		return m.LoadBalanceRequestType
+	}
+	return nil
+}
+
+func (m *LoadBalanceRequest) GetInitialRequest() *InitialLoadBalanceRequest {
+	if x, ok := m.GetLoadBalanceRequestType().(*LoadBalanceRequest_InitialRequest); ok {
+		return x.InitialRequest
+	}
+	return nil
+}
+
+func (m *LoadBalanceRequest) GetClientStats() *ClientStats {
+	if x, ok := m.GetLoadBalanceRequestType().(*LoadBalanceRequest_ClientStats); ok {
+		return x.ClientStats
+	}
+	return nil
+}
+
+// XXX_OneofWrappers is for the internal use of the proto package.
+func (*LoadBalanceRequest) XXX_OneofWrappers() []interface{} {
+	return []interface{}{
+		(*LoadBalanceRequest_InitialRequest)(nil),
+		(*LoadBalanceRequest_ClientStats)(nil),
+	}
+}
+
+type InitialLoadBalanceRequest struct {
+	// The name of the load balanced service (e.g., service.googleapis.com). Its
+	// length should be less than 256 bytes.
+	// The name might include a port number. How to handle the port number is up
+	// to the balancer.
+	Name                 string   `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *InitialLoadBalanceRequest) Reset()         { *m = InitialLoadBalanceRequest{} }
+func (m *InitialLoadBalanceRequest) String() string { return proto.CompactTextString(m) }
+func (*InitialLoadBalanceRequest) ProtoMessage()    {}
+func (*InitialLoadBalanceRequest) Descriptor() ([]byte, []int) {
+	return fileDescriptor_7cd3f6d792743fdf, []int{1}
+}
+
+func (m *InitialLoadBalanceRequest) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_InitialLoadBalanceRequest.Unmarshal(m, b)
+}
+func (m *InitialLoadBalanceRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_InitialLoadBalanceRequest.Marshal(b, m, deterministic)
+}
+func (m *InitialLoadBalanceRequest) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_InitialLoadBalanceRequest.Merge(m, src)
+}
+func (m *InitialLoadBalanceRequest) XXX_Size() int {
+	return xxx_messageInfo_InitialLoadBalanceRequest.Size(m)
+}
+func (m *InitialLoadBalanceRequest) XXX_DiscardUnknown() {
+	xxx_messageInfo_InitialLoadBalanceRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_InitialLoadBalanceRequest proto.InternalMessageInfo
+
+func (m *InitialLoadBalanceRequest) GetName() string {
+	if m != nil {
+		return m.Name
+	}
+	return ""
+}
+
+// Contains the number of calls finished for a particular load balance token.
+type ClientStatsPerToken struct {
+	// See Server.load_balance_token.
+	LoadBalanceToken string `protobuf:"bytes,1,opt,name=load_balance_token,json=loadBalanceToken,proto3" json:"load_balance_token,omitempty"`
+	// The total number of RPCs that finished associated with the token.
+	NumCalls             int64    `protobuf:"varint,2,opt,name=num_calls,json=numCalls,proto3" json:"num_calls,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *ClientStatsPerToken) Reset()         { *m = ClientStatsPerToken{} }
+func (m *ClientStatsPerToken) String() string { return proto.CompactTextString(m) }
+func (*ClientStatsPerToken) ProtoMessage()    {}
+func (*ClientStatsPerToken) Descriptor() ([]byte, []int) {
+	return fileDescriptor_7cd3f6d792743fdf, []int{2}
+}
+
+func (m *ClientStatsPerToken) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_ClientStatsPerToken.Unmarshal(m, b)
+}
+func (m *ClientStatsPerToken) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_ClientStatsPerToken.Marshal(b, m, deterministic)
+}
+func (m *ClientStatsPerToken) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_ClientStatsPerToken.Merge(m, src)
+}
+func (m *ClientStatsPerToken) XXX_Size() int {
+	return xxx_messageInfo_ClientStatsPerToken.Size(m)
+}
+func (m *ClientStatsPerToken) XXX_DiscardUnknown() {
+	xxx_messageInfo_ClientStatsPerToken.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ClientStatsPerToken proto.InternalMessageInfo
+
+func (m *ClientStatsPerToken) GetLoadBalanceToken() string {
+	if m != nil {
+		return m.LoadBalanceToken
+	}
+	return ""
+}
+
+func (m *ClientStatsPerToken) GetNumCalls() int64 {
+	if m != nil {
+		return m.NumCalls
+	}
+	return 0
+}
+
+// Contains client level statistics that are useful to load balancing. Each
+// count except the timestamp should be reset to zero after reporting the stats.
+type ClientStats struct {
+	// The timestamp of generating the report.
+	Timestamp *timestamp.Timestamp `protobuf:"bytes,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
+	// The total number of RPCs that started.
+	NumCallsStarted int64 `protobuf:"varint,2,opt,name=num_calls_started,json=numCallsStarted,proto3" json:"num_calls_started,omitempty"`
+	// The total number of RPCs that finished.
+	NumCallsFinished int64 `protobuf:"varint,3,opt,name=num_calls_finished,json=numCallsFinished,proto3" json:"num_calls_finished,omitempty"`
+	// The total number of RPCs that failed to reach a server except dropped RPCs.
+	NumCallsFinishedWithClientFailedToSend int64 `protobuf:"varint,6,opt,name=num_calls_finished_with_client_failed_to_send,json=numCallsFinishedWithClientFailedToSend,proto3" json:"num_calls_finished_with_client_failed_to_send,omitempty"`
+	// The total number of RPCs that finished and are known to have been received
+	// by a server.
+	NumCallsFinishedKnownReceived int64 `protobuf:"varint,7,opt,name=num_calls_finished_known_received,json=numCallsFinishedKnownReceived,proto3" json:"num_calls_finished_known_received,omitempty"`
+	// The list of dropped calls.
+	CallsFinishedWithDrop []*ClientStatsPerToken `protobuf:"bytes,8,rep,name=calls_finished_with_drop,json=callsFinishedWithDrop,proto3" json:"calls_finished_with_drop,omitempty"`
+	XXX_NoUnkeyedLiteral  struct{}               `json:"-"`
+	XXX_unrecognized      []byte                 `json:"-"`
+	XXX_sizecache         int32                  `json:"-"`
+}
+
+func (m *ClientStats) Reset()         { *m = ClientStats{} }
+func (m *ClientStats) String() string { return proto.CompactTextString(m) }
+func (*ClientStats) ProtoMessage()    {}
+func (*ClientStats) Descriptor() ([]byte, []int) {
+	return fileDescriptor_7cd3f6d792743fdf, []int{3}
+}
+
+func (m *ClientStats) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_ClientStats.Unmarshal(m, b)
+}
+func (m *ClientStats) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_ClientStats.Marshal(b, m, deterministic)
+}
+func (m *ClientStats) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_ClientStats.Merge(m, src)
+}
+func (m *ClientStats) XXX_Size() int {
+	return xxx_messageInfo_ClientStats.Size(m)
+}
+func (m *ClientStats) XXX_DiscardUnknown() {
+	xxx_messageInfo_ClientStats.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ClientStats proto.InternalMessageInfo
+
+func (m *ClientStats) GetTimestamp() *timestamp.Timestamp {
+	if m != nil {
+		return m.Timestamp
+	}
+	return nil
+}
+
+func (m *ClientStats) GetNumCallsStarted() int64 {
+	if m != nil {
+		return m.NumCallsStarted
+	}
+	return 0
+}
+
+func (m *ClientStats) GetNumCallsFinished() int64 {
+	if m != nil {
+		return m.NumCallsFinished
+	}
+	return 0
+}
+
+func (m *ClientStats) GetNumCallsFinishedWithClientFailedToSend() int64 {
+	if m != nil {
+		return m.NumCallsFinishedWithClientFailedToSend
+	}
+	return 0
+}
+
+func (m *ClientStats) GetNumCallsFinishedKnownReceived() int64 {
+	if m != nil {
+		return m.NumCallsFinishedKnownReceived
+	}
+	return 0
+}
+
+func (m *ClientStats) GetCallsFinishedWithDrop() []*ClientStatsPerToken {
+	if m != nil {
+		return m.CallsFinishedWithDrop
+	}
+	return nil
+}
+
+type LoadBalanceResponse struct {
+	// Types that are valid to be assigned to LoadBalanceResponseType:
+	//	*LoadBalanceResponse_InitialResponse
+	//	*LoadBalanceResponse_ServerList
+	//	*LoadBalanceResponse_FallbackResponse
+	LoadBalanceResponseType isLoadBalanceResponse_LoadBalanceResponseType `protobuf_oneof:"load_balance_response_type"`
+	XXX_NoUnkeyedLiteral    struct{}                                      `json:"-"`
+	XXX_unrecognized        []byte                                        `json:"-"`
+	XXX_sizecache           int32                                         `json:"-"`
+}
+
+func (m *LoadBalanceResponse) Reset()         { *m = LoadBalanceResponse{} }
+func (m *LoadBalanceResponse) String() string { return proto.CompactTextString(m) }
+func (*LoadBalanceResponse) ProtoMessage()    {}
+func (*LoadBalanceResponse) Descriptor() ([]byte, []int) {
+	return fileDescriptor_7cd3f6d792743fdf, []int{4}
+}
+
+func (m *LoadBalanceResponse) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_LoadBalanceResponse.Unmarshal(m, b)
+}
+func (m *LoadBalanceResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_LoadBalanceResponse.Marshal(b, m, deterministic)
+}
+func (m *LoadBalanceResponse) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_LoadBalanceResponse.Merge(m, src)
+}
+func (m *LoadBalanceResponse) XXX_Size() int {
+	return xxx_messageInfo_LoadBalanceResponse.Size(m)
+}
+func (m *LoadBalanceResponse) XXX_DiscardUnknown() {
+	xxx_messageInfo_LoadBalanceResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_LoadBalanceResponse proto.InternalMessageInfo
+
+type isLoadBalanceResponse_LoadBalanceResponseType interface {
+	isLoadBalanceResponse_LoadBalanceResponseType()
+}
+
+type LoadBalanceResponse_InitialResponse struct {
+	InitialResponse *InitialLoadBalanceResponse `protobuf:"bytes,1,opt,name=initial_response,json=initialResponse,proto3,oneof"`
+}
+
+type LoadBalanceResponse_ServerList struct {
+	ServerList *ServerList `protobuf:"bytes,2,opt,name=server_list,json=serverList,proto3,oneof"`
+}
+
+type LoadBalanceResponse_FallbackResponse struct {
+	FallbackResponse *FallbackResponse `protobuf:"bytes,3,opt,name=fallback_response,json=fallbackResponse,proto3,oneof"`
+}
+
+func (*LoadBalanceResponse_InitialResponse) isLoadBalanceResponse_LoadBalanceResponseType() {}
+
+func (*LoadBalanceResponse_ServerList) isLoadBalanceResponse_LoadBalanceResponseType() {}
+
+func (*LoadBalanceResponse_FallbackResponse) isLoadBalanceResponse_LoadBalanceResponseType() {}
+
+func (m *LoadBalanceResponse) GetLoadBalanceResponseType() isLoadBalanceResponse_LoadBalanceResponseType {
+	if m != nil {
+		return m.LoadBalanceResponseType
+	}
+	return nil
+}
+
+func (m *LoadBalanceResponse) GetInitialResponse() *InitialLoadBalanceResponse {
+	if x, ok := m.GetLoadBalanceResponseType().(*LoadBalanceResponse_InitialResponse); ok {
+		return x.InitialResponse
+	}
+	return nil
+}
+
+func (m *LoadBalanceResponse) GetServerList() *ServerList {
+	if x, ok := m.GetLoadBalanceResponseType().(*LoadBalanceResponse_ServerList); ok {
+		return x.ServerList
+	}
+	return nil
+}
+
+func (m *LoadBalanceResponse) GetFallbackResponse() *FallbackResponse {
+	if x, ok := m.GetLoadBalanceResponseType().(*LoadBalanceResponse_FallbackResponse); ok {
+		return x.FallbackResponse
+	}
+	return nil
+}
+
+// XXX_OneofWrappers is for the internal use of the proto package.
+func (*LoadBalanceResponse) XXX_OneofWrappers() []interface{} {
+	return []interface{}{
+		(*LoadBalanceResponse_InitialResponse)(nil),
+		(*LoadBalanceResponse_ServerList)(nil),
+		(*LoadBalanceResponse_FallbackResponse)(nil),
+	}
+}
+
+type FallbackResponse struct {
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *FallbackResponse) Reset()         { *m = FallbackResponse{} }
+func (m *FallbackResponse) String() string { return proto.CompactTextString(m) }
+func (*FallbackResponse) ProtoMessage()    {}
+func (*FallbackResponse) Descriptor() ([]byte, []int) {
+	return fileDescriptor_7cd3f6d792743fdf, []int{5}
+}
+
+func (m *FallbackResponse) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_FallbackResponse.Unmarshal(m, b)
+}
+func (m *FallbackResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_FallbackResponse.Marshal(b, m, deterministic)
+}
+func (m *FallbackResponse) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_FallbackResponse.Merge(m, src)
+}
+func (m *FallbackResponse) XXX_Size() int {
+	return xxx_messageInfo_FallbackResponse.Size(m)
+}
+func (m *FallbackResponse) XXX_DiscardUnknown() {
+	xxx_messageInfo_FallbackResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_FallbackResponse proto.InternalMessageInfo
+
+type InitialLoadBalanceResponse struct {
+	// This is an application layer redirect that indicates the client should use
+	// the specified server for load balancing. When this field is non-empty in
+	// the response, the client should open a separate connection to the
+	// load_balancer_delegate and call the BalanceLoad method. Its length should
+	// be less than 64 bytes.
+	LoadBalancerDelegate string `protobuf:"bytes,1,opt,name=load_balancer_delegate,json=loadBalancerDelegate,proto3" json:"load_balancer_delegate,omitempty"`
+	// This interval defines how often the client should send the client stats
+	// to the load balancer. Stats should only be reported when the duration is
+	// positive.
+	ClientStatsReportInterval *duration.Duration `protobuf:"bytes,2,opt,name=client_stats_report_interval,json=clientStatsReportInterval,proto3" json:"client_stats_report_interval,omitempty"`
+	XXX_NoUnkeyedLiteral      struct{}           `json:"-"`
+	XXX_unrecognized          []byte             `json:"-"`
+	XXX_sizecache             int32              `json:"-"`
+}
+
+func (m *InitialLoadBalanceResponse) Reset()         { *m = InitialLoadBalanceResponse{} }
+func (m *InitialLoadBalanceResponse) String() string { return proto.CompactTextString(m) }
+func (*InitialLoadBalanceResponse) ProtoMessage()    {}
+func (*InitialLoadBalanceResponse) Descriptor() ([]byte, []int) {
+	return fileDescriptor_7cd3f6d792743fdf, []int{6}
+}
+
+func (m *InitialLoadBalanceResponse) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_InitialLoadBalanceResponse.Unmarshal(m, b)
+}
+func (m *InitialLoadBalanceResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_InitialLoadBalanceResponse.Marshal(b, m, deterministic)
+}
+func (m *InitialLoadBalanceResponse) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_InitialLoadBalanceResponse.Merge(m, src)
+}
+func (m *InitialLoadBalanceResponse) XXX_Size() int {
+	return xxx_messageInfo_InitialLoadBalanceResponse.Size(m)
+}
+func (m *InitialLoadBalanceResponse) XXX_DiscardUnknown() {
+	xxx_messageInfo_InitialLoadBalanceResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_InitialLoadBalanceResponse proto.InternalMessageInfo
+
+func (m *InitialLoadBalanceResponse) GetLoadBalancerDelegate() string {
+	if m != nil {
+		return m.LoadBalancerDelegate
+	}
+	return ""
+}
+
+func (m *InitialLoadBalanceResponse) GetClientStatsReportInterval() *duration.Duration {
+	if m != nil {
+		return m.ClientStatsReportInterval
+	}
+	return nil
+}
+
+type ServerList struct {
+	// Contains a list of servers selected by the load balancer. The list will
+	// be updated when server resolutions change or as needed to balance load
+	// across more servers. The client should consume the server list in order
+	// unless instructed otherwise via the client_config.
+	Servers              []*Server `protobuf:"bytes,1,rep,name=servers,proto3" json:"servers,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}  `json:"-"`
+	XXX_unrecognized     []byte    `json:"-"`
+	XXX_sizecache        int32     `json:"-"`
+}
+
+func (m *ServerList) Reset()         { *m = ServerList{} }
+func (m *ServerList) String() string { return proto.CompactTextString(m) }
+func (*ServerList) ProtoMessage()    {}
+func (*ServerList) Descriptor() ([]byte, []int) {
+	return fileDescriptor_7cd3f6d792743fdf, []int{7}
+}
+
+func (m *ServerList) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_ServerList.Unmarshal(m, b)
+}
+func (m *ServerList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_ServerList.Marshal(b, m, deterministic)
+}
+func (m *ServerList) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_ServerList.Merge(m, src)
+}
+func (m *ServerList) XXX_Size() int {
+	return xxx_messageInfo_ServerList.Size(m)
+}
+func (m *ServerList) XXX_DiscardUnknown() {
+	xxx_messageInfo_ServerList.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ServerList proto.InternalMessageInfo
+
+func (m *ServerList) GetServers() []*Server {
+	if m != nil {
+		return m.Servers
+	}
+	return nil
+}
+
+// Contains server information. When the drop field is not true, use the other
+// fields.
+type Server struct {
+	// A resolved address for the server, serialized in network-byte-order. It may
+	// either be an IPv4 or IPv6 address.
+	IpAddress []byte `protobuf:"bytes,1,opt,name=ip_address,json=ipAddress,proto3" json:"ip_address,omitempty"`
+	// A resolved port number for the server.
+	Port int32 `protobuf:"varint,2,opt,name=port,proto3" json:"port,omitempty"`
+	// An opaque but printable token for load reporting. The client must include
+	// the token of the picked server into the initial metadata when it starts a
+	// call to that server. The token is used by the server to verify the request
+	// and to allow the server to report load to the gRPC LB system. The token is
+	// also used in client stats for reporting dropped calls.
+	//
+	// Its length can be variable but must be less than 50 bytes.
+	LoadBalanceToken string `protobuf:"bytes,3,opt,name=load_balance_token,json=loadBalanceToken,proto3" json:"load_balance_token,omitempty"`
+	// Indicates whether this particular request should be dropped by the client.
+	// If the request is dropped, there will be a corresponding entry in
+	// ClientStats.calls_finished_with_drop.
+	Drop                 bool     `protobuf:"varint,4,opt,name=drop,proto3" json:"drop,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *Server) Reset()         { *m = Server{} }
+func (m *Server) String() string { return proto.CompactTextString(m) }
+func (*Server) ProtoMessage()    {}
+func (*Server) Descriptor() ([]byte, []int) {
+	return fileDescriptor_7cd3f6d792743fdf, []int{8}
+}
+
+func (m *Server) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Server.Unmarshal(m, b)
+}
+func (m *Server) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Server.Marshal(b, m, deterministic)
+}
+func (m *Server) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Server.Merge(m, src)
+}
+func (m *Server) XXX_Size() int {
+	return xxx_messageInfo_Server.Size(m)
+}
+func (m *Server) XXX_DiscardUnknown() {
+	xxx_messageInfo_Server.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Server proto.InternalMessageInfo
+
+func (m *Server) GetIpAddress() []byte {
+	if m != nil {
+		return m.IpAddress
+	}
+	return nil
+}
+
+func (m *Server) GetPort() int32 {
+	if m != nil {
+		return m.Port
+	}
+	return 0
+}
+
+func (m *Server) GetLoadBalanceToken() string {
+	if m != nil {
+		return m.LoadBalanceToken
+	}
+	return ""
+}
+
+func (m *Server) GetDrop() bool {
+	if m != nil {
+		return m.Drop
+	}
+	return false
+}
+
+func init() {
+	proto.RegisterType((*LoadBalanceRequest)(nil), "grpc.lb.v1.LoadBalanceRequest")
+	proto.RegisterType((*InitialLoadBalanceRequest)(nil), "grpc.lb.v1.InitialLoadBalanceRequest")
+	proto.RegisterType((*ClientStatsPerToken)(nil), "grpc.lb.v1.ClientStatsPerToken")
+	proto.RegisterType((*ClientStats)(nil), "grpc.lb.v1.ClientStats")
+	proto.RegisterType((*LoadBalanceResponse)(nil), "grpc.lb.v1.LoadBalanceResponse")
+	proto.RegisterType((*FallbackResponse)(nil), "grpc.lb.v1.FallbackResponse")
+	proto.RegisterType((*InitialLoadBalanceResponse)(nil), "grpc.lb.v1.InitialLoadBalanceResponse")
+	proto.RegisterType((*ServerList)(nil), "grpc.lb.v1.ServerList")
+	proto.RegisterType((*Server)(nil), "grpc.lb.v1.Server")
+}
+
+func init() { proto.RegisterFile("grpc/lb/v1/load_balancer.proto", fileDescriptor_7cd3f6d792743fdf) }
+
+var fileDescriptor_7cd3f6d792743fdf = []byte{
+	// 785 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x55, 0xdd, 0x6e, 0xdb, 0x36,
+	0x14, 0x8e, 0x6a, 0x27, 0x75, 0x8e, 0xb3, 0xc5, 0x61, 0xb7, 0x4e, 0x71, 0xd3, 0x24, 0x13, 0xb0,
+	0x22, 0x18, 0x3a, 0x79, 0xc9, 0x76, 0xb1, 0x01, 0xbb, 0xd8, 0xdc, 0x20, 0x48, 0xd3, 0x5e, 0x04,
+	0x74, 0x80, 0x0e, 0x05, 0x06, 0x8e, 0x92, 0x68, 0x87, 0x08, 0x4d, 0x6a, 0x14, 0xed, 0x62, 0xd7,
+	0x7b, 0x81, 0x3d, 0xc9, 0xb0, 0x57, 0xd8, 0x9b, 0x0d, 0x22, 0x29, 0x4b, 0xb1, 0x63, 0xf4, 0x4a,
+	0xe4, 0x39, 0x1f, 0xbf, 0xf3, 0x7f, 0x04, 0x87, 0x13, 0x9d, 0xa7, 0x03, 0x91, 0x0c, 0xe6, 0xa7,
+	0x03, 0xa1, 0x68, 0x46, 0x12, 0x2a, 0xa8, 0x4c, 0x99, 0x8e, 0x73, 0xad, 0x8c, 0x42, 0x50, 0xea,
+	0x63, 0x91, 0xc4, 0xf3, 0xd3, 0xfe, 0xe1, 0x44, 0xa9, 0x89, 0x60, 0x03, 0xab, 0x49, 0x66, 0xe3,
+	0x41, 0x36, 0xd3, 0xd4, 0x70, 0x25, 0x1d, 0xb6, 0x7f, 0xb4, 0xac, 0x37, 0x7c, 0xca, 0x0a, 0x43,
+	0xa7, 0xb9, 0x03, 0x44, 0xff, 0x05, 0x80, 0xde, 0x2a, 0x9a, 0x0d, 0x9d, 0x0d, 0xcc, 0xfe, 0x98,
+	0xb1, 0xc2, 0xa0, 0x6b, 0xd8, 0xe5, 0x92, 0x1b, 0x4e, 0x05, 0xd1, 0x4e, 0x14, 0x06, 0xc7, 0xc1,
+	0x49, 0xf7, 0xec, 0xab, 0xb8, 0xb6, 0x1e, 0xbf, 0x76, 0x90, 0xd5, 0xf7, 0x97, 0x1b, 0xf8, 0x53,
+	0xff, 0xbe, 0x62, 0xfc, 0x09, 0x76, 0x52, 0xc1, 0x99, 0x34, 0xa4, 0x30, 0xd4, 0x14, 0xe1, 0x23,
+	0x4b, 0xf7, 0x45, 0x93, 0xee, 0x95, 0xd5, 0x8f, 0x4a, 0xf5, 0xe5, 0x06, 0xee, 0xa6, 0xf5, 0x75,
+	0xf8, 0x0c, 0xf6, 0x9b, 0xa9, 0xa8, 0x9c, 0x22, 0xe6, 0xcf, 0x9c, 0x45, 0x03, 0xd8, 0x5f, 0xeb,
+	0x09, 0x42, 0xd0, 0x96, 0x74, 0xca, 0xac, 0xfb, 0xdb, 0xd8, 0x9e, 0xa3, 0xdf, 0xe1, 0x49, 0xc3,
+	0xd6, 0x35, 0xd3, 0x37, 0xea, 0x8e, 0x49, 0xf4, 0x12, 0xd0, 0x3d, 0x23, 0xa6, 0x94, 0xfa, 0x87,
+	0x3d, 0x51, 0x53, 0x3b, 0xf4, 0x33, 0xd8, 0x96, 0xb3, 0x29, 0x49, 0xa9, 0x10, 0x2e, 0x9a, 0x16,
+	0xee, 0xc8, 0xd9, 0xf4, 0x55, 0x79, 0x8f, 0xfe, 0x6d, 0x41, 0xb7, 0x61, 0x02, 0xfd, 0x00, 0xdb,
+	0x8b, 0xcc, 0xfb, 0x4c, 0xf6, 0x63, 0x57, 0x9b, 0xb8, 0xaa, 0x4d, 0x7c, 0x53, 0x21, 0x70, 0x0d,
+	0x46, 0x5f, 0xc3, 0xde, 0xc2, 0x4c, 0x99, 0x3a, 0x6d, 0x58, 0xe6, 0xcd, 0xed, 0x56, 0xe6, 0x46,
+	0x4e, 0x5c, 0x06, 0x50, 0x63, 0xc7, 0x5c, 0xf2, 0xe2, 0x96, 0x65, 0x61, 0xcb, 0x82, 0x7b, 0x15,
+	0xf8, 0xc2, 0xcb, 0xd1, 0x6f, 0xf0, 0xcd, 0x2a, 0x9a, 0x7c, 0xe0, 0xe6, 0x96, 0xf8, 0x4a, 0x8d,
+	0x29, 0x17, 0x2c, 0x23, 0x46, 0x91, 0x82, 0xc9, 0x2c, 0xdc, 0xb2, 0x44, 0x2f, 0x96, 0x89, 0xde,
+	0x71, 0x73, 0xeb, 0x62, 0xbd, 0xb0, 0xf8, 0x1b, 0x35, 0x62, 0x32, 0x43, 0x97, 0xf0, 0xe5, 0x03,
+	0xf4, 0x77, 0x52, 0x7d, 0x90, 0x44, 0xb3, 0x94, 0xf1, 0x39, 0xcb, 0xc2, 0xc7, 0x96, 0xf2, 0xf9,
+	0x32, 0xe5, 0x9b, 0x12, 0x85, 0x3d, 0x08, 0xfd, 0x0a, 0xe1, 0x43, 0x4e, 0x66, 0x5a, 0xe5, 0x61,
+	0xe7, 0xb8, 0x75, 0xd2, 0x3d, 0x3b, 0x5a, 0xd3, 0x46, 0x55, 0x69, 0xf1, 0xe7, 0xe9, 0xb2, 0xc7,
+	0xe7, 0x5a, 0xe5, 0x57, 0xed, 0x4e, 0xbb, 0xb7, 0x79, 0xd5, 0xee, 0x6c, 0xf6, 0xb6, 0xa2, 0xbf,
+	0x1f, 0xc1, 0x93, 0x7b, 0xfd, 0x53, 0xe4, 0x4a, 0x16, 0x0c, 0x8d, 0xa0, 0x57, 0x8f, 0x82, 0x93,
+	0xf9, 0x0a, 0xbe, 0xf8, 0xd8, 0x2c, 0x38, 0xf4, 0xe5, 0x06, 0xde, 0x5d, 0x0c, 0x83, 0x27, 0xfd,
+	0x11, 0xba, 0x05, 0xd3, 0x73, 0xa6, 0x89, 0xe0, 0x85, 0xf1, 0xc3, 0xf0, 0xb4, 0xc9, 0x37, 0xb2,
+	0xea, 0xb7, 0xdc, 0x0e, 0x13, 0x14, 0x8b, 0x1b, 0x7a, 0x03, 0x7b, 0x63, 0x2a, 0x44, 0x42, 0xd3,
+	0xbb, 0xda, 0xa1, 0x96, 0x25, 0x38, 0x68, 0x12, 0x5c, 0x78, 0x50, 0xc3, 0x8d, 0xde, 0x78, 0x49,
+	0x36, 0x3c, 0x80, 0xfe, 0xd2, 0x5c, 0x39, 0x85, 0x1b, 0x2c, 0x04, 0xbd, 0x65, 0x96, 0xe8, 0x9f,
+	0x00, 0xfa, 0xeb, 0x63, 0x45, 0xdf, 0xc3, 0xd3, 0x7b, 0x3b, 0x8b, 0x64, 0x4c, 0xb0, 0x09, 0x35,
+	0xd5, 0x00, 0x7e, 0xd6, 0x98, 0x23, 0x7d, 0xee, 0x75, 0xe8, 0x3d, 0x1c, 0x34, 0x97, 0x03, 0xd1,
+	0x2c, 0x57, 0xda, 0x10, 0x2e, 0x0d, 0xd3, 0x73, 0x2a, 0x7c, 0x7e, 0xf6, 0x57, 0x26, 0xe6, 0xdc,
+	0x6f, 0x3b, 0xbc, 0xdf, 0x58, 0x16, 0xd8, 0x3e, 0x7e, 0xed, 0xdf, 0x46, 0x3f, 0x03, 0xd4, 0xb9,
+	0x44, 0x2f, 0xe1, 0xb1, 0xcb, 0x65, 0x11, 0x06, 0xb6, 0x75, 0xd0, 0x6a, 0xd2, 0x71, 0x05, 0xb9,
+	0x6a, 0x77, 0x5a, 0xbd, 0x76, 0xf4, 0x57, 0x00, 0x5b, 0x4e, 0x83, 0x9e, 0x03, 0xf0, 0x9c, 0xd0,
+	0x2c, 0xd3, 0xac, 0x28, 0x6c, 0x48, 0x3b, 0x78, 0x9b, 0xe7, 0xbf, 0x38, 0x41, 0xb9, 0x6c, 0x4a,
+	0xdb, 0xd6, 0xdf, 0x4d, 0x6c, 0xcf, 0x6b, 0xb6, 0x4a, 0x6b, 0xcd, 0x56, 0x41, 0xd0, 0xb6, 0x7d,
+	0xdd, 0x3e, 0x0e, 0x4e, 0x3a, 0xd8, 0x9e, 0x5d, 0x7f, 0x9e, 0x25, 0xb0, 0xd3, 0x48, 0xb8, 0x46,
+	0x18, 0xba, 0xfe, 0x5c, 0x8a, 0xd1, 0x61, 0x33, 0x8e, 0xd5, 0x3d, 0xd8, 0x3f, 0x5a, 0xab, 0x77,
+	0x95, 0x3b, 0x09, 0xbe, 0x0d, 0x86, 0xef, 0xe0, 0x13, 0xae, 0x1a, 0xc0, 0xe1, 0x5e, 0xd3, 0xe4,
+	0x75, 0x99, 0xf6, 0xeb, 0xe0, 0xfd, 0xa9, 0x2f, 0xc3, 0x44, 0x09, 0x2a, 0x27, 0xb1, 0xd2, 0x93,
+	0x81, 0xfd, 0x65, 0x55, 0x35, 0xb7, 0x37, 0x91, 0xd8, 0x0f, 0x11, 0x09, 0x99, 0x9f, 0x26, 0x5b,
+	0xb6, 0x64, 0xdf, 0xfd, 0x1f, 0x00, 0x00, 0xff, 0xff, 0x09, 0x7b, 0x39, 0x1e, 0xdc, 0x06, 0x00,
+	0x00,
+}
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ context.Context
+var _ grpc.ClientConn
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+const _ = grpc.SupportPackageIsVersion4
+
+// LoadBalancerClient is the client API for LoadBalancer service.
+//
+// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
+type LoadBalancerClient interface {
+	// Bidirectional rpc to get a list of servers.
+	BalanceLoad(ctx context.Context, opts ...grpc.CallOption) (LoadBalancer_BalanceLoadClient, error)
+}
+
+type loadBalancerClient struct {
+	cc *grpc.ClientConn
+}
+
+func NewLoadBalancerClient(cc *grpc.ClientConn) LoadBalancerClient {
+	return &loadBalancerClient{cc}
+}
+
+func (c *loadBalancerClient) BalanceLoad(ctx context.Context, opts ...grpc.CallOption) (LoadBalancer_BalanceLoadClient, error) {
+	stream, err := c.cc.NewStream(ctx, &_LoadBalancer_serviceDesc.Streams[0], "/grpc.lb.v1.LoadBalancer/BalanceLoad", opts...)
+	if err != nil {
+		return nil, err
+	}
+	x := &loadBalancerBalanceLoadClient{stream}
+	return x, nil
+}
+
+type LoadBalancer_BalanceLoadClient interface {
+	Send(*LoadBalanceRequest) error
+	Recv() (*LoadBalanceResponse, error)
+	grpc.ClientStream
+}
+
+type loadBalancerBalanceLoadClient struct {
+	grpc.ClientStream
+}
+
+func (x *loadBalancerBalanceLoadClient) Send(m *LoadBalanceRequest) error {
+	return x.ClientStream.SendMsg(m)
+}
+
+func (x *loadBalancerBalanceLoadClient) Recv() (*LoadBalanceResponse, error) {
+	m := new(LoadBalanceResponse)
+	if err := x.ClientStream.RecvMsg(m); err != nil {
+		return nil, err
+	}
+	return m, nil
+}
+
+// LoadBalancerServer is the server API for LoadBalancer service.
+type LoadBalancerServer interface {
+	// Bidirectional rpc to get a list of servers.
+	BalanceLoad(LoadBalancer_BalanceLoadServer) error
+}
+
+// UnimplementedLoadBalancerServer can be embedded to have forward compatible implementations.
+type UnimplementedLoadBalancerServer struct {
+}
+
+func (*UnimplementedLoadBalancerServer) BalanceLoad(srv LoadBalancer_BalanceLoadServer) error {
+	return status.Errorf(codes.Unimplemented, "method BalanceLoad not implemented")
+}
+
+func RegisterLoadBalancerServer(s *grpc.Server, srv LoadBalancerServer) {
+	s.RegisterService(&_LoadBalancer_serviceDesc, srv)
+}
+
+func _LoadBalancer_BalanceLoad_Handler(srv interface{}, stream grpc.ServerStream) error {
+	return srv.(LoadBalancerServer).BalanceLoad(&loadBalancerBalanceLoadServer{stream})
+}
+
+type LoadBalancer_BalanceLoadServer interface {
+	Send(*LoadBalanceResponse) error
+	Recv() (*LoadBalanceRequest, error)
+	grpc.ServerStream
+}
+
+type loadBalancerBalanceLoadServer struct {
+	grpc.ServerStream
+}
+
+func (x *loadBalancerBalanceLoadServer) Send(m *LoadBalanceResponse) error {
+	return x.ServerStream.SendMsg(m)
+}
+
+func (x *loadBalancerBalanceLoadServer) Recv() (*LoadBalanceRequest, error) {
+	m := new(LoadBalanceRequest)
+	if err := x.ServerStream.RecvMsg(m); err != nil {
+		return nil, err
+	}
+	return m, nil
+}
+
+var _LoadBalancer_serviceDesc = grpc.ServiceDesc{
+	ServiceName: "grpc.lb.v1.LoadBalancer",
+	HandlerType: (*LoadBalancerServer)(nil),
+	Methods:     []grpc.MethodDesc{},
+	Streams: []grpc.StreamDesc{
+		{
+			StreamName:    "BalanceLoad",
+			Handler:       _LoadBalancer_BalanceLoad_Handler,
+			ServerStreams: true,
+			ClientStreams: true,
+		},
+	},
+	Metadata: "grpc/lb/v1/load_balancer.proto",
+}

+ 488 - 0
vendor/google.golang.org/grpc/balancer/grpclb/grpclb.go

@@ -0,0 +1,488 @@
+/*
+ *
+ * Copyright 2016 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+//go:generate ./regenerate.sh
+
+// Package grpclb defines a grpclb balancer.
+//
+// To install grpclb balancer, import this package as:
+//    import _ "google.golang.org/grpc/balancer/grpclb"
+package grpclb
+
+import (
+	"context"
+	"errors"
+	"sync"
+	"time"
+
+	durationpb "github.com/golang/protobuf/ptypes/duration"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/balancer"
+	lbpb "google.golang.org/grpc/balancer/grpclb/grpc_lb_v1"
+	"google.golang.org/grpc/connectivity"
+	"google.golang.org/grpc/credentials"
+	"google.golang.org/grpc/grpclog"
+	"google.golang.org/grpc/internal"
+	"google.golang.org/grpc/internal/backoff"
+	"google.golang.org/grpc/internal/resolver/dns"
+	"google.golang.org/grpc/resolver"
+)
+
+const (
+	lbTokenKey             = "lb-token"
+	defaultFallbackTimeout = 10 * time.Second
+	grpclbName             = "grpclb"
+)
+
+var errServerTerminatedConnection = errors.New("grpclb: failed to recv server list: server terminated connection")
+
+func convertDuration(d *durationpb.Duration) time.Duration {
+	if d == nil {
+		return 0
+	}
+	return time.Duration(d.Seconds)*time.Second + time.Duration(d.Nanos)*time.Nanosecond
+}
+
+// Client API for LoadBalancer service.
+// Mostly copied from generated pb.go file.
+// To avoid circular dependency.
+type loadBalancerClient struct {
+	cc *grpc.ClientConn
+}
+
+func (c *loadBalancerClient) BalanceLoad(ctx context.Context, opts ...grpc.CallOption) (*balanceLoadClientStream, error) {
+	desc := &grpc.StreamDesc{
+		StreamName:    "BalanceLoad",
+		ServerStreams: true,
+		ClientStreams: true,
+	}
+	stream, err := c.cc.NewStream(ctx, desc, "/grpc.lb.v1.LoadBalancer/BalanceLoad", opts...)
+	if err != nil {
+		return nil, err
+	}
+	x := &balanceLoadClientStream{stream}
+	return x, nil
+}
+
+type balanceLoadClientStream struct {
+	grpc.ClientStream
+}
+
+func (x *balanceLoadClientStream) Send(m *lbpb.LoadBalanceRequest) error {
+	return x.ClientStream.SendMsg(m)
+}
+
+func (x *balanceLoadClientStream) Recv() (*lbpb.LoadBalanceResponse, error) {
+	m := new(lbpb.LoadBalanceResponse)
+	if err := x.ClientStream.RecvMsg(m); err != nil {
+		return nil, err
+	}
+	return m, nil
+}
+
+func init() {
+	balancer.Register(newLBBuilder())
+	dns.EnableSRVLookups = true
+}
+
+// newLBBuilder creates a builder for grpclb.
+func newLBBuilder() balancer.Builder {
+	return newLBBuilderWithFallbackTimeout(defaultFallbackTimeout)
+}
+
+// newLBBuilderWithFallbackTimeout creates a grpclb builder with the given
+// fallbackTimeout. If no response is received from the remote balancer within
+// fallbackTimeout, the backend addresses from the resolved address list will be
+// used.
+//
+// Only call this function when a non-default fallback timeout is needed.
+func newLBBuilderWithFallbackTimeout(fallbackTimeout time.Duration) balancer.Builder {
+	return &lbBuilder{
+		fallbackTimeout: fallbackTimeout,
+	}
+}
+
+type lbBuilder struct {
+	fallbackTimeout time.Duration
+}
+
+func (b *lbBuilder) Name() string {
+	return grpclbName
+}
+
+func (b *lbBuilder) Build(cc balancer.ClientConn, opt balancer.BuildOptions) balancer.Balancer {
+	// This generates a manual resolver builder with a fixed scheme. This
+	// scheme will be used to dial to remote LB, so we can send filtered
+	// address updates to remote LB ClientConn using this manual resolver.
+	r := &lbManualResolver{scheme: "grpclb-internal", ccb: cc}
+
+	lb := &lbBalancer{
+		cc:              newLBCacheClientConn(cc),
+		target:          opt.Target.Endpoint,
+		opt:             opt,
+		fallbackTimeout: b.fallbackTimeout,
+		doneCh:          make(chan struct{}),
+
+		manualResolver: r,
+		subConns:       make(map[resolver.Address]balancer.SubConn),
+		scStates:       make(map[balancer.SubConn]connectivity.State),
+		picker:         &errPicker{err: balancer.ErrNoSubConnAvailable},
+		clientStats:    newRPCStats(),
+		backoff:        backoff.DefaultExponential, // TODO: make backoff configurable.
+	}
+
+	var err error
+	if opt.CredsBundle != nil {
+		lb.grpclbClientConnCreds, err = opt.CredsBundle.NewWithMode(internal.CredsBundleModeBalancer)
+		if err != nil {
+			grpclog.Warningf("lbBalancer: client connection creds NewWithMode failed: %v", err)
+		}
+		lb.grpclbBackendCreds, err = opt.CredsBundle.NewWithMode(internal.CredsBundleModeBackendFromBalancer)
+		if err != nil {
+			grpclog.Warningf("lbBalancer: backend creds NewWithMode failed: %v", err)
+		}
+	}
+
+	return lb
+}
+
+var _ balancer.V2Balancer = (*lbBalancer)(nil) // Assert that we implement V2Balancer
+
+type lbBalancer struct {
+	cc     *lbCacheClientConn
+	target string
+	opt    balancer.BuildOptions
+
+	usePickFirst bool
+
+	// grpclbClientConnCreds is the creds bundle to be used to connect to grpclb
+	// servers. If it's nil, use the TransportCredentials from BuildOptions
+	// instead.
+	grpclbClientConnCreds credentials.Bundle
+	// grpclbBackendCreds is the creds bundle to be used for addresses that are
+	// returned by grpclb server. If it's nil, don't set anything when creating
+	// SubConns.
+	grpclbBackendCreds credentials.Bundle
+
+	fallbackTimeout time.Duration
+	doneCh          chan struct{}
+
+	// manualResolver is used in the remote LB ClientConn inside grpclb. When
+	// resolved address updates are received by grpclb, filtered updates will be
+	// send to remote LB ClientConn through this resolver.
+	manualResolver *lbManualResolver
+	// The ClientConn to talk to the remote balancer.
+	ccRemoteLB *remoteBalancerCCWrapper
+	// backoff for calling remote balancer.
+	backoff backoff.Strategy
+
+	// Support client side load reporting. Each picker gets a reference to this,
+	// and will update its content.
+	clientStats *rpcStats
+
+	mu sync.Mutex // guards everything following.
+	// The full server list including drops, used to check if the newly received
+	// serverList contains anything new. Each generate picker will also have
+	// reference to this list to do the first layer pick.
+	fullServerList []*lbpb.Server
+	// Backend addresses. It's kept so the addresses are available when
+	// switching between round_robin and pickfirst.
+	backendAddrs []resolver.Address
+	// All backends addresses, with metadata set to nil. This list contains all
+	// backend addresses in the same order and with the same duplicates as in
+	// serverlist. When generating picker, a SubConn slice with the same order
+	// but with only READY SCs will be gerenated.
+	backendAddrsWithoutMetadata []resolver.Address
+	// Roundrobin functionalities.
+	state    connectivity.State
+	subConns map[resolver.Address]balancer.SubConn   // Used to new/remove SubConn.
+	scStates map[balancer.SubConn]connectivity.State // Used to filter READY SubConns.
+	picker   balancer.V2Picker
+	// Support fallback to resolved backend addresses if there's no response
+	// from remote balancer within fallbackTimeout.
+	remoteBalancerConnected bool
+	serverListReceived      bool
+	inFallback              bool
+	// resolvedBackendAddrs is resolvedAddrs minus remote balancers. It's set
+	// when resolved address updates are received, and read in the goroutine
+	// handling fallback.
+	resolvedBackendAddrs []resolver.Address
+}
+
+// regeneratePicker takes a snapshot of the balancer, and generates a picker from
+// it. The picker
+//  - always returns ErrTransientFailure if the balancer is in TransientFailure,
+//  - does two layer roundrobin pick otherwise.
+// Caller must hold lb.mu.
+func (lb *lbBalancer) regeneratePicker(resetDrop bool) {
+	if lb.state == connectivity.TransientFailure {
+		lb.picker = &errPicker{err: balancer.ErrTransientFailure}
+		return
+	}
+
+	if lb.state == connectivity.Connecting {
+		lb.picker = &errPicker{err: balancer.ErrNoSubConnAvailable}
+		return
+	}
+
+	var readySCs []balancer.SubConn
+	if lb.usePickFirst {
+		for _, sc := range lb.subConns {
+			readySCs = append(readySCs, sc)
+			break
+		}
+	} else {
+		for _, a := range lb.backendAddrsWithoutMetadata {
+			if sc, ok := lb.subConns[a]; ok {
+				if st, ok := lb.scStates[sc]; ok && st == connectivity.Ready {
+					readySCs = append(readySCs, sc)
+				}
+			}
+		}
+	}
+
+	if len(readySCs) <= 0 {
+		// If there's no ready SubConns, always re-pick. This is to avoid drops
+		// unless at least one SubConn is ready. Otherwise we may drop more
+		// often than want because of drops + re-picks(which become re-drops).
+		//
+		// This doesn't seem to be necessary after the connecting check above.
+		// Kept for safety.
+		lb.picker = &errPicker{err: balancer.ErrNoSubConnAvailable}
+		return
+	}
+	if lb.inFallback {
+		lb.picker = newRRPicker(readySCs)
+		return
+	}
+	if resetDrop {
+		lb.picker = newLBPicker(lb.fullServerList, readySCs, lb.clientStats)
+		return
+	}
+	prevLBPicker, ok := lb.picker.(*lbPicker)
+	if !ok {
+		lb.picker = newLBPicker(lb.fullServerList, readySCs, lb.clientStats)
+		return
+	}
+	prevLBPicker.updateReadySCs(readySCs)
+}
+
+// aggregateSubConnStats calculate the aggregated state of SubConns in
+// lb.SubConns. These SubConns are subconns in use (when switching between
+// fallback and grpclb). lb.scState contains states for all SubConns, including
+// those in cache (SubConns are cached for 10 seconds after remove).
+//
+// The aggregated state is:
+//  - If at least one SubConn in Ready, the aggregated state is Ready;
+//  - Else if at least one SubConn in Connecting, the aggregated state is Connecting;
+//  - Else the aggregated state is TransientFailure.
+func (lb *lbBalancer) aggregateSubConnStates() connectivity.State {
+	var numConnecting uint64
+
+	for _, sc := range lb.subConns {
+		if state, ok := lb.scStates[sc]; ok {
+			switch state {
+			case connectivity.Ready:
+				return connectivity.Ready
+			case connectivity.Connecting:
+				numConnecting++
+			}
+		}
+	}
+	if numConnecting > 0 {
+		return connectivity.Connecting
+	}
+	return connectivity.TransientFailure
+}
+
+func (lb *lbBalancer) HandleSubConnStateChange(sc balancer.SubConn, s connectivity.State) {
+	panic("not used")
+}
+
+func (lb *lbBalancer) UpdateSubConnState(sc balancer.SubConn, scs balancer.SubConnState) {
+	s := scs.ConnectivityState
+	if grpclog.V(2) {
+		grpclog.Infof("lbBalancer: handle SubConn state change: %p, %v", sc, s)
+	}
+	lb.mu.Lock()
+	defer lb.mu.Unlock()
+
+	oldS, ok := lb.scStates[sc]
+	if !ok {
+		if grpclog.V(2) {
+			grpclog.Infof("lbBalancer: got state changes for an unknown SubConn: %p, %v", sc, s)
+		}
+		return
+	}
+	lb.scStates[sc] = s
+	switch s {
+	case connectivity.Idle:
+		sc.Connect()
+	case connectivity.Shutdown:
+		// When an address was removed by resolver, b called RemoveSubConn but
+		// kept the sc's state in scStates. Remove state for this sc here.
+		delete(lb.scStates, sc)
+	}
+	// Force regenerate picker if
+	//  - this sc became ready from not-ready
+	//  - this sc became not-ready from ready
+	lb.updateStateAndPicker((oldS == connectivity.Ready) != (s == connectivity.Ready), false)
+
+	// Enter fallback when the aggregated state is not Ready and the connection
+	// to remote balancer is lost.
+	if lb.state != connectivity.Ready {
+		if !lb.inFallback && !lb.remoteBalancerConnected {
+			// Enter fallback.
+			lb.refreshSubConns(lb.resolvedBackendAddrs, true, lb.usePickFirst)
+		}
+	}
+}
+
+// updateStateAndPicker re-calculate the aggregated state, and regenerate picker
+// if overall state is changed.
+//
+// If forceRegeneratePicker is true, picker will be regenerated.
+func (lb *lbBalancer) updateStateAndPicker(forceRegeneratePicker bool, resetDrop bool) {
+	oldAggrState := lb.state
+	lb.state = lb.aggregateSubConnStates()
+	// Regenerate picker when one of the following happens:
+	//  - caller wants to regenerate
+	//  - the aggregated state changed
+	if forceRegeneratePicker || (lb.state != oldAggrState) {
+		lb.regeneratePicker(resetDrop)
+	}
+
+	lb.cc.UpdateState(balancer.State{ConnectivityState: lb.state, Picker: lb.picker})
+}
+
+// fallbackToBackendsAfter blocks for fallbackTimeout and falls back to use
+// resolved backends (backends received from resolver, not from remote balancer)
+// if no connection to remote balancers was successful.
+func (lb *lbBalancer) fallbackToBackendsAfter(fallbackTimeout time.Duration) {
+	timer := time.NewTimer(fallbackTimeout)
+	defer timer.Stop()
+	select {
+	case <-timer.C:
+	case <-lb.doneCh:
+		return
+	}
+	lb.mu.Lock()
+	if lb.inFallback || lb.serverListReceived {
+		lb.mu.Unlock()
+		return
+	}
+	// Enter fallback.
+	lb.refreshSubConns(lb.resolvedBackendAddrs, true, lb.usePickFirst)
+	lb.mu.Unlock()
+}
+
+// HandleResolvedAddrs sends the updated remoteLB addresses to remoteLB
+// clientConn. The remoteLB clientConn will handle creating/removing remoteLB
+// connections.
+func (lb *lbBalancer) HandleResolvedAddrs(addrs []resolver.Address, err error) {
+	panic("not used")
+}
+
+func (lb *lbBalancer) handleServiceConfig(gc *grpclbServiceConfig) {
+	lb.mu.Lock()
+	defer lb.mu.Unlock()
+
+	newUsePickFirst := childIsPickFirst(gc)
+	if lb.usePickFirst == newUsePickFirst {
+		return
+	}
+	if grpclog.V(2) {
+		grpclog.Infof("lbBalancer: switching mode, new usePickFirst: %+v", newUsePickFirst)
+	}
+	lb.refreshSubConns(lb.backendAddrs, lb.inFallback, newUsePickFirst)
+}
+
+func (lb *lbBalancer) ResolverError(error) {
+	// Ignore resolver errors.  GRPCLB is not selected unless the resolver
+	// works at least once.
+}
+
+func (lb *lbBalancer) UpdateClientConnState(ccs balancer.ClientConnState) error {
+	if grpclog.V(2) {
+		grpclog.Infof("lbBalancer: UpdateClientConnState: %+v", ccs)
+	}
+	gc, _ := ccs.BalancerConfig.(*grpclbServiceConfig)
+	lb.handleServiceConfig(gc)
+
+	addrs := ccs.ResolverState.Addresses
+	if len(addrs) == 0 {
+		// There should be at least one address, either grpclb server or
+		// fallback. Empty address is not valid.
+		return balancer.ErrBadResolverState
+	}
+
+	var remoteBalancerAddrs, backendAddrs []resolver.Address
+	for _, a := range addrs {
+		if a.Type == resolver.GRPCLB {
+			a.Type = resolver.Backend
+			remoteBalancerAddrs = append(remoteBalancerAddrs, a)
+		} else {
+			backendAddrs = append(backendAddrs, a)
+		}
+	}
+
+	if len(remoteBalancerAddrs) == 0 {
+		if lb.ccRemoteLB != nil {
+			lb.ccRemoteLB.close()
+			lb.ccRemoteLB = nil
+		}
+	} else if lb.ccRemoteLB == nil {
+		// First time receiving resolved addresses, create a cc to remote
+		// balancers.
+		lb.newRemoteBalancerCCWrapper()
+		// Start the fallback goroutine.
+		go lb.fallbackToBackendsAfter(lb.fallbackTimeout)
+	}
+
+	if lb.ccRemoteLB != nil {
+		// cc to remote balancers uses lb.manualResolver. Send the updated remote
+		// balancer addresses to it through manualResolver.
+		lb.manualResolver.UpdateState(resolver.State{Addresses: remoteBalancerAddrs})
+	}
+
+	lb.mu.Lock()
+	lb.resolvedBackendAddrs = backendAddrs
+	if len(remoteBalancerAddrs) == 0 || lb.inFallback {
+		// If there's no remote balancer address in ClientConn update, grpclb
+		// enters fallback mode immediately.
+		//
+		// If a new update is received while grpclb is in fallback, update the
+		// list of backends being used to the new fallback backends.
+		lb.refreshSubConns(lb.resolvedBackendAddrs, true, lb.usePickFirst)
+	}
+	lb.mu.Unlock()
+	return nil
+}
+
+func (lb *lbBalancer) Close() {
+	select {
+	case <-lb.doneCh:
+		return
+	default:
+	}
+	close(lb.doneCh)
+	if lb.ccRemoteLB != nil {
+		lb.ccRemoteLB.close()
+	}
+	lb.cc.close()
+}

+ 66 - 0
vendor/google.golang.org/grpc/balancer/grpclb/grpclb_config.go

@@ -0,0 +1,66 @@
+/*
+ *
+ * Copyright 2019 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package grpclb
+
+import (
+	"encoding/json"
+
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/balancer/roundrobin"
+	"google.golang.org/grpc/serviceconfig"
+)
+
+const (
+	roundRobinName = roundrobin.Name
+	pickFirstName  = grpc.PickFirstBalancerName
+)
+
+type grpclbServiceConfig struct {
+	serviceconfig.LoadBalancingConfig
+	ChildPolicy *[]map[string]json.RawMessage
+}
+
+func (b *lbBuilder) ParseConfig(lbConfig json.RawMessage) (serviceconfig.LoadBalancingConfig, error) {
+	ret := &grpclbServiceConfig{}
+	if err := json.Unmarshal(lbConfig, ret); err != nil {
+		return nil, err
+	}
+	return ret, nil
+}
+
+func childIsPickFirst(sc *grpclbServiceConfig) bool {
+	if sc == nil {
+		return false
+	}
+	childConfigs := sc.ChildPolicy
+	if childConfigs == nil {
+		return false
+	}
+	for _, childC := range *childConfigs {
+		// If round_robin exists before pick_first, return false
+		if _, ok := childC[roundRobinName]; ok {
+			return false
+		}
+		// If pick_first is before round_robin, return true
+		if _, ok := childC[pickFirstName]; ok {
+			return true
+		}
+	}
+	return false
+}

+ 202 - 0
vendor/google.golang.org/grpc/balancer/grpclb/grpclb_picker.go

@@ -0,0 +1,202 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package grpclb
+
+import (
+	"sync"
+	"sync/atomic"
+
+	"google.golang.org/grpc/balancer"
+	lbpb "google.golang.org/grpc/balancer/grpclb/grpc_lb_v1"
+	"google.golang.org/grpc/codes"
+	"google.golang.org/grpc/internal/grpcrand"
+	"google.golang.org/grpc/status"
+)
+
+// rpcStats is same as lbpb.ClientStats, except that numCallsDropped is a map
+// instead of a slice.
+type rpcStats struct {
+	// Only access the following fields atomically.
+	numCallsStarted                        int64
+	numCallsFinished                       int64
+	numCallsFinishedWithClientFailedToSend int64
+	numCallsFinishedKnownReceived          int64
+
+	mu sync.Mutex
+	// map load_balance_token -> num_calls_dropped
+	numCallsDropped map[string]int64
+}
+
+func newRPCStats() *rpcStats {
+	return &rpcStats{
+		numCallsDropped: make(map[string]int64),
+	}
+}
+
+func isZeroStats(stats *lbpb.ClientStats) bool {
+	return len(stats.CallsFinishedWithDrop) == 0 &&
+		stats.NumCallsStarted == 0 &&
+		stats.NumCallsFinished == 0 &&
+		stats.NumCallsFinishedWithClientFailedToSend == 0 &&
+		stats.NumCallsFinishedKnownReceived == 0
+}
+
+// toClientStats converts rpcStats to lbpb.ClientStats, and clears rpcStats.
+func (s *rpcStats) toClientStats() *lbpb.ClientStats {
+	stats := &lbpb.ClientStats{
+		NumCallsStarted:                        atomic.SwapInt64(&s.numCallsStarted, 0),
+		NumCallsFinished:                       atomic.SwapInt64(&s.numCallsFinished, 0),
+		NumCallsFinishedWithClientFailedToSend: atomic.SwapInt64(&s.numCallsFinishedWithClientFailedToSend, 0),
+		NumCallsFinishedKnownReceived:          atomic.SwapInt64(&s.numCallsFinishedKnownReceived, 0),
+	}
+	s.mu.Lock()
+	dropped := s.numCallsDropped
+	s.numCallsDropped = make(map[string]int64)
+	s.mu.Unlock()
+	for token, count := range dropped {
+		stats.CallsFinishedWithDrop = append(stats.CallsFinishedWithDrop, &lbpb.ClientStatsPerToken{
+			LoadBalanceToken: token,
+			NumCalls:         count,
+		})
+	}
+	return stats
+}
+
+func (s *rpcStats) drop(token string) {
+	atomic.AddInt64(&s.numCallsStarted, 1)
+	s.mu.Lock()
+	s.numCallsDropped[token]++
+	s.mu.Unlock()
+	atomic.AddInt64(&s.numCallsFinished, 1)
+}
+
+func (s *rpcStats) failedToSend() {
+	atomic.AddInt64(&s.numCallsStarted, 1)
+	atomic.AddInt64(&s.numCallsFinishedWithClientFailedToSend, 1)
+	atomic.AddInt64(&s.numCallsFinished, 1)
+}
+
+func (s *rpcStats) knownReceived() {
+	atomic.AddInt64(&s.numCallsStarted, 1)
+	atomic.AddInt64(&s.numCallsFinishedKnownReceived, 1)
+	atomic.AddInt64(&s.numCallsFinished, 1)
+}
+
+type errPicker struct {
+	// Pick always returns this err.
+	err error
+}
+
+func (p *errPicker) Pick(balancer.PickInfo) (balancer.PickResult, error) {
+	return balancer.PickResult{}, p.err
+}
+
+// rrPicker does roundrobin on subConns. It's typically used when there's no
+// response from remote balancer, and grpclb falls back to the resolved
+// backends.
+//
+// It guaranteed that len(subConns) > 0.
+type rrPicker struct {
+	mu           sync.Mutex
+	subConns     []balancer.SubConn // The subConns that were READY when taking the snapshot.
+	subConnsNext int
+}
+
+func newRRPicker(readySCs []balancer.SubConn) *rrPicker {
+	return &rrPicker{
+		subConns:     readySCs,
+		subConnsNext: grpcrand.Intn(len(readySCs)),
+	}
+}
+
+func (p *rrPicker) Pick(balancer.PickInfo) (balancer.PickResult, error) {
+	p.mu.Lock()
+	defer p.mu.Unlock()
+	sc := p.subConns[p.subConnsNext]
+	p.subConnsNext = (p.subConnsNext + 1) % len(p.subConns)
+	return balancer.PickResult{SubConn: sc}, nil
+}
+
+// lbPicker does two layers of picks:
+//
+// First layer: roundrobin on all servers in serverList, including drops and backends.
+// - If it picks a drop, the RPC will fail as being dropped.
+// - If it picks a backend, do a second layer pick to pick the real backend.
+//
+// Second layer: roundrobin on all READY backends.
+//
+// It's guaranteed that len(serverList) > 0.
+type lbPicker struct {
+	mu             sync.Mutex
+	serverList     []*lbpb.Server
+	serverListNext int
+	subConns       []balancer.SubConn // The subConns that were READY when taking the snapshot.
+	subConnsNext   int
+
+	stats *rpcStats
+}
+
+func newLBPicker(serverList []*lbpb.Server, readySCs []balancer.SubConn, stats *rpcStats) *lbPicker {
+	return &lbPicker{
+		serverList:   serverList,
+		subConns:     readySCs,
+		subConnsNext: grpcrand.Intn(len(readySCs)),
+		stats:        stats,
+	}
+}
+
+func (p *lbPicker) Pick(balancer.PickInfo) (balancer.PickResult, error) {
+	p.mu.Lock()
+	defer p.mu.Unlock()
+
+	// Layer one roundrobin on serverList.
+	s := p.serverList[p.serverListNext]
+	p.serverListNext = (p.serverListNext + 1) % len(p.serverList)
+
+	// If it's a drop, return an error and fail the RPC.
+	if s.Drop {
+		p.stats.drop(s.LoadBalanceToken)
+		return balancer.PickResult{}, status.Errorf(codes.Unavailable, "request dropped by grpclb")
+	}
+
+	// If not a drop but there's no ready subConns.
+	if len(p.subConns) <= 0 {
+		return balancer.PickResult{}, balancer.ErrNoSubConnAvailable
+	}
+
+	// Return the next ready subConn in the list, also collect rpc stats.
+	sc := p.subConns[p.subConnsNext]
+	p.subConnsNext = (p.subConnsNext + 1) % len(p.subConns)
+	done := func(info balancer.DoneInfo) {
+		if !info.BytesSent {
+			p.stats.failedToSend()
+		} else if info.BytesReceived {
+			p.stats.knownReceived()
+		}
+	}
+	return balancer.PickResult{SubConn: sc, Done: done}, nil
+}
+
+func (p *lbPicker) updateReadySCs(readySCs []balancer.SubConn) {
+	p.mu.Lock()
+	defer p.mu.Unlock()
+
+	p.subConns = readySCs
+	p.subConnsNext = p.subConnsNext % len(readySCs)
+}

+ 407 - 0
vendor/google.golang.org/grpc/balancer/grpclb/grpclb_remote_balancer.go

@@ -0,0 +1,407 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package grpclb
+
+import (
+	"context"
+	"fmt"
+	"io"
+	"net"
+	"sync"
+	"time"
+
+	"github.com/golang/protobuf/proto"
+	timestamppb "github.com/golang/protobuf/ptypes/timestamp"
+	"github.com/google/go-cmp/cmp"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/balancer"
+	lbpb "google.golang.org/grpc/balancer/grpclb/grpc_lb_v1"
+	"google.golang.org/grpc/connectivity"
+	"google.golang.org/grpc/grpclog"
+	"google.golang.org/grpc/internal/backoff"
+	"google.golang.org/grpc/internal/channelz"
+	"google.golang.org/grpc/keepalive"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/grpc/resolver"
+)
+
+// processServerList updates balaner's internal state, create/remove SubConns
+// and regenerates picker using the received serverList.
+func (lb *lbBalancer) processServerList(l *lbpb.ServerList) {
+	if grpclog.V(2) {
+		grpclog.Infof("lbBalancer: processing server list: %+v", l)
+	}
+	lb.mu.Lock()
+	defer lb.mu.Unlock()
+
+	// Set serverListReceived to true so fallback will not take effect if it has
+	// not hit timeout.
+	lb.serverListReceived = true
+
+	// If the new server list == old server list, do nothing.
+	if cmp.Equal(lb.fullServerList, l.Servers, cmp.Comparer(proto.Equal)) {
+		if grpclog.V(2) {
+			grpclog.Infof("lbBalancer: new serverlist same as the previous one, ignoring")
+		}
+		return
+	}
+	lb.fullServerList = l.Servers
+
+	var backendAddrs []resolver.Address
+	for i, s := range l.Servers {
+		if s.Drop {
+			continue
+		}
+
+		md := metadata.Pairs(lbTokenKey, s.LoadBalanceToken)
+		ip := net.IP(s.IpAddress)
+		ipStr := ip.String()
+		if ip.To4() == nil {
+			// Add square brackets to ipv6 addresses, otherwise net.Dial() and
+			// net.SplitHostPort() will return too many colons error.
+			ipStr = fmt.Sprintf("[%s]", ipStr)
+		}
+		addr := resolver.Address{
+			Addr:     fmt.Sprintf("%s:%d", ipStr, s.Port),
+			Metadata: &md,
+		}
+		if grpclog.V(2) {
+			grpclog.Infof("lbBalancer: server list entry[%d]: ipStr:|%s|, port:|%d|, load balancer token:|%v|",
+				i, ipStr, s.Port, s.LoadBalanceToken)
+		}
+		backendAddrs = append(backendAddrs, addr)
+	}
+
+	// Call refreshSubConns to create/remove SubConns.  If we are in fallback,
+	// this is also exiting fallback.
+	lb.refreshSubConns(backendAddrs, false, lb.usePickFirst)
+}
+
+// refreshSubConns creates/removes SubConns with backendAddrs, and refreshes
+// balancer state and picker.
+//
+// Caller must hold lb.mu.
+func (lb *lbBalancer) refreshSubConns(backendAddrs []resolver.Address, fallback bool, pickFirst bool) {
+	opts := balancer.NewSubConnOptions{}
+	if !fallback {
+		opts.CredsBundle = lb.grpclbBackendCreds
+	}
+
+	lb.backendAddrs = backendAddrs
+	lb.backendAddrsWithoutMetadata = nil
+
+	fallbackModeChanged := lb.inFallback != fallback
+	lb.inFallback = fallback
+	if fallbackModeChanged && lb.inFallback {
+		// Clear previous received list when entering fallback, so if the server
+		// comes back and sends the same list again, the new addresses will be
+		// used.
+		lb.fullServerList = nil
+	}
+
+	balancingPolicyChanged := lb.usePickFirst != pickFirst
+	oldUsePickFirst := lb.usePickFirst
+	lb.usePickFirst = pickFirst
+
+	if fallbackModeChanged || balancingPolicyChanged {
+		// Remove all SubConns when switching balancing policy or switching
+		// fallback mode.
+		//
+		// For fallback mode switching with pickfirst, we want to recreate the
+		// SubConn because the creds could be different.
+		for a, sc := range lb.subConns {
+			if oldUsePickFirst {
+				// If old SubConn were created for pickfirst, bypass cache and
+				// remove directly.
+				lb.cc.cc.RemoveSubConn(sc)
+			} else {
+				lb.cc.RemoveSubConn(sc)
+			}
+			delete(lb.subConns, a)
+		}
+	}
+
+	if lb.usePickFirst {
+		var sc balancer.SubConn
+		for _, sc = range lb.subConns {
+			break
+		}
+		if sc != nil {
+			sc.UpdateAddresses(backendAddrs)
+			sc.Connect()
+			return
+		}
+		// This bypasses the cc wrapper with SubConn cache.
+		sc, err := lb.cc.cc.NewSubConn(backendAddrs, opts)
+		if err != nil {
+			grpclog.Warningf("grpclb: failed to create new SubConn: %v", err)
+			return
+		}
+		sc.Connect()
+		lb.subConns[backendAddrs[0]] = sc
+		lb.scStates[sc] = connectivity.Idle
+		return
+	}
+
+	// addrsSet is the set converted from backendAddrsWithoutMetadata, it's used to quick
+	// lookup for an address.
+	addrsSet := make(map[resolver.Address]struct{})
+	// Create new SubConns.
+	for _, addr := range backendAddrs {
+		addrWithoutMD := addr
+		addrWithoutMD.Metadata = nil
+		addrsSet[addrWithoutMD] = struct{}{}
+		lb.backendAddrsWithoutMetadata = append(lb.backendAddrsWithoutMetadata, addrWithoutMD)
+
+		if _, ok := lb.subConns[addrWithoutMD]; !ok {
+			// Use addrWithMD to create the SubConn.
+			sc, err := lb.cc.NewSubConn([]resolver.Address{addr}, opts)
+			if err != nil {
+				grpclog.Warningf("grpclb: failed to create new SubConn: %v", err)
+				continue
+			}
+			lb.subConns[addrWithoutMD] = sc // Use the addr without MD as key for the map.
+			if _, ok := lb.scStates[sc]; !ok {
+				// Only set state of new sc to IDLE. The state could already be
+				// READY for cached SubConns.
+				lb.scStates[sc] = connectivity.Idle
+			}
+			sc.Connect()
+		}
+	}
+
+	for a, sc := range lb.subConns {
+		// a was removed by resolver.
+		if _, ok := addrsSet[a]; !ok {
+			lb.cc.RemoveSubConn(sc)
+			delete(lb.subConns, a)
+			// Keep the state of this sc in b.scStates until sc's state becomes Shutdown.
+			// The entry will be deleted in HandleSubConnStateChange.
+		}
+	}
+
+	// Regenerate and update picker after refreshing subconns because with
+	// cache, even if SubConn was newed/removed, there might be no state
+	// changes (the subconn will be kept in cache, not actually
+	// newed/removed).
+	lb.updateStateAndPicker(true, true)
+}
+
+type remoteBalancerCCWrapper struct {
+	cc      *grpc.ClientConn
+	lb      *lbBalancer
+	backoff backoff.Strategy
+	done    chan struct{}
+
+	// waitgroup to wait for all goroutines to exit.
+	wg sync.WaitGroup
+}
+
+func (lb *lbBalancer) newRemoteBalancerCCWrapper() {
+	var dopts []grpc.DialOption
+	if creds := lb.opt.DialCreds; creds != nil {
+		dopts = append(dopts, grpc.WithTransportCredentials(creds))
+	} else if bundle := lb.grpclbClientConnCreds; bundle != nil {
+		dopts = append(dopts, grpc.WithCredentialsBundle(bundle))
+	} else {
+		dopts = append(dopts, grpc.WithInsecure())
+	}
+	if lb.opt.Dialer != nil {
+		dopts = append(dopts, grpc.WithContextDialer(lb.opt.Dialer))
+	}
+	// Explicitly set pickfirst as the balancer.
+	dopts = append(dopts, grpc.WithDefaultServiceConfig(`{"loadBalancingPolicy":"pick_first"}`))
+	dopts = append(dopts, grpc.WithResolvers(lb.manualResolver))
+	if channelz.IsOn() {
+		dopts = append(dopts, grpc.WithChannelzParentID(lb.opt.ChannelzParentID))
+	}
+
+	// Enable Keepalive for grpclb client.
+	dopts = append(dopts, grpc.WithKeepaliveParams(keepalive.ClientParameters{
+		Time:                20 * time.Second,
+		Timeout:             10 * time.Second,
+		PermitWithoutStream: true,
+	}))
+
+	// The dial target is not important.
+	//
+	// The grpclb server addresses will set field ServerName, and creds will
+	// receive ServerName as authority.
+	cc, err := grpc.DialContext(context.Background(), lb.manualResolver.Scheme()+":///grpclb.subClientConn", dopts...)
+	if err != nil {
+		grpclog.Fatalf("failed to dial: %v", err)
+	}
+	ccw := &remoteBalancerCCWrapper{
+		cc:      cc,
+		lb:      lb,
+		backoff: lb.backoff,
+		done:    make(chan struct{}),
+	}
+	lb.ccRemoteLB = ccw
+	ccw.wg.Add(1)
+	go ccw.watchRemoteBalancer()
+}
+
+// close closed the ClientConn to remote balancer, and waits until all
+// goroutines to finish.
+func (ccw *remoteBalancerCCWrapper) close() {
+	close(ccw.done)
+	ccw.cc.Close()
+	ccw.wg.Wait()
+}
+
+func (ccw *remoteBalancerCCWrapper) readServerList(s *balanceLoadClientStream) error {
+	for {
+		reply, err := s.Recv()
+		if err != nil {
+			if err == io.EOF {
+				return errServerTerminatedConnection
+			}
+			return fmt.Errorf("grpclb: failed to recv server list: %v", err)
+		}
+		if serverList := reply.GetServerList(); serverList != nil {
+			ccw.lb.processServerList(serverList)
+		}
+	}
+}
+
+func (ccw *remoteBalancerCCWrapper) sendLoadReport(s *balanceLoadClientStream, interval time.Duration) {
+	ticker := time.NewTicker(interval)
+	defer ticker.Stop()
+	lastZero := false
+	for {
+		select {
+		case <-ticker.C:
+		case <-s.Context().Done():
+			return
+		}
+		stats := ccw.lb.clientStats.toClientStats()
+		zero := isZeroStats(stats)
+		if zero && lastZero {
+			// Quash redundant empty load reports.
+			continue
+		}
+		lastZero = zero
+		t := time.Now()
+		stats.Timestamp = &timestamppb.Timestamp{
+			Seconds: t.Unix(),
+			Nanos:   int32(t.Nanosecond()),
+		}
+		if err := s.Send(&lbpb.LoadBalanceRequest{
+			LoadBalanceRequestType: &lbpb.LoadBalanceRequest_ClientStats{
+				ClientStats: stats,
+			},
+		}); err != nil {
+			return
+		}
+	}
+}
+
+func (ccw *remoteBalancerCCWrapper) callRemoteBalancer() (backoff bool, _ error) {
+	lbClient := &loadBalancerClient{cc: ccw.cc}
+	ctx, cancel := context.WithCancel(context.Background())
+	defer cancel()
+	stream, err := lbClient.BalanceLoad(ctx, grpc.WaitForReady(true))
+	if err != nil {
+		return true, fmt.Errorf("grpclb: failed to perform RPC to the remote balancer %v", err)
+	}
+	ccw.lb.mu.Lock()
+	ccw.lb.remoteBalancerConnected = true
+	ccw.lb.mu.Unlock()
+
+	// grpclb handshake on the stream.
+	initReq := &lbpb.LoadBalanceRequest{
+		LoadBalanceRequestType: &lbpb.LoadBalanceRequest_InitialRequest{
+			InitialRequest: &lbpb.InitialLoadBalanceRequest{
+				Name: ccw.lb.target,
+			},
+		},
+	}
+	if err := stream.Send(initReq); err != nil {
+		return true, fmt.Errorf("grpclb: failed to send init request: %v", err)
+	}
+	reply, err := stream.Recv()
+	if err != nil {
+		return true, fmt.Errorf("grpclb: failed to recv init response: %v", err)
+	}
+	initResp := reply.GetInitialResponse()
+	if initResp == nil {
+		return true, fmt.Errorf("grpclb: reply from remote balancer did not include initial response")
+	}
+	if initResp.LoadBalancerDelegate != "" {
+		return true, fmt.Errorf("grpclb: Delegation is not supported")
+	}
+
+	ccw.wg.Add(1)
+	go func() {
+		defer ccw.wg.Done()
+		if d := convertDuration(initResp.ClientStatsReportInterval); d > 0 {
+			ccw.sendLoadReport(stream, d)
+		}
+	}()
+	// No backoff if init req/resp handshake was successful.
+	return false, ccw.readServerList(stream)
+}
+
+func (ccw *remoteBalancerCCWrapper) watchRemoteBalancer() {
+	defer ccw.wg.Done()
+	var retryCount int
+	for {
+		doBackoff, err := ccw.callRemoteBalancer()
+		select {
+		case <-ccw.done:
+			return
+		default:
+			if err != nil {
+				if err == errServerTerminatedConnection {
+					grpclog.Info(err)
+				} else {
+					grpclog.Warning(err)
+				}
+			}
+		}
+		// Trigger a re-resolve when the stream errors.
+		ccw.lb.cc.cc.ResolveNow(resolver.ResolveNowOptions{})
+
+		ccw.lb.mu.Lock()
+		ccw.lb.remoteBalancerConnected = false
+		ccw.lb.fullServerList = nil
+		// Enter fallback when connection to remote balancer is lost, and the
+		// aggregated state is not Ready.
+		if !ccw.lb.inFallback && ccw.lb.state != connectivity.Ready {
+			// Entering fallback.
+			ccw.lb.refreshSubConns(ccw.lb.resolvedBackendAddrs, true, ccw.lb.usePickFirst)
+		}
+		ccw.lb.mu.Unlock()
+
+		if !doBackoff {
+			retryCount = 0
+			continue
+		}
+
+		timer := time.NewTimer(ccw.backoff.Backoff(retryCount)) // Copy backoff
+		select {
+		case <-timer.C:
+		case <-ccw.done:
+			timer.Stop()
+			return
+		}
+		retryCount++
+	}
+}

+ 208 - 0
vendor/google.golang.org/grpc/balancer/grpclb/grpclb_util.go

@@ -0,0 +1,208 @@
+/*
+ *
+ * Copyright 2016 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package grpclb
+
+import (
+	"fmt"
+	"sync"
+	"time"
+
+	"google.golang.org/grpc/balancer"
+	"google.golang.org/grpc/resolver"
+)
+
+// The parent ClientConn should re-resolve when grpclb loses connection to the
+// remote balancer. When the ClientConn inside grpclb gets a TransientFailure,
+// it calls lbManualResolver.ResolveNow(), which calls parent ClientConn's
+// ResolveNow, and eventually results in re-resolve happening in parent
+// ClientConn's resolver (DNS for example).
+//
+//                          parent
+//                          ClientConn
+//  +-----------------------------------------------------------------+
+//  |             parent          +---------------------------------+ |
+//  | DNS         ClientConn      |  grpclb                         | |
+//  | resolver    balancerWrapper |                                 | |
+//  | +              +            |    grpclb          grpclb       | |
+//  | |              |            |    ManualResolver  ClientConn   | |
+//  | |              |            |     +              +            | |
+//  | |              |            |     |              | Transient  | |
+//  | |              |            |     |              | Failure    | |
+//  | |              |            |     |  <---------  |            | |
+//  | |              | <--------------- |  ResolveNow  |            | |
+//  | |  <---------  | ResolveNow |     |              |            | |
+//  | |  ResolveNow  |            |     |              |            | |
+//  | |              |            |     |              |            | |
+//  | +              +            |     +              +            | |
+//  |                             +---------------------------------+ |
+//  +-----------------------------------------------------------------+
+
+// lbManualResolver is used by the ClientConn inside grpclb. It's a manual
+// resolver with a special ResolveNow() function.
+//
+// When ResolveNow() is called, it calls ResolveNow() on the parent ClientConn,
+// so when grpclb client lose contact with remote balancers, the parent
+// ClientConn's resolver will re-resolve.
+type lbManualResolver struct {
+	scheme string
+	ccr    resolver.ClientConn
+
+	ccb balancer.ClientConn
+}
+
+func (r *lbManualResolver) Build(_ resolver.Target, cc resolver.ClientConn, _ resolver.BuildOptions) (resolver.Resolver, error) {
+	r.ccr = cc
+	return r, nil
+}
+
+func (r *lbManualResolver) Scheme() string {
+	return r.scheme
+}
+
+// ResolveNow calls resolveNow on the parent ClientConn.
+func (r *lbManualResolver) ResolveNow(o resolver.ResolveNowOptions) {
+	r.ccb.ResolveNow(o)
+}
+
+// Close is a noop for Resolver.
+func (*lbManualResolver) Close() {}
+
+// UpdateState calls cc.UpdateState.
+func (r *lbManualResolver) UpdateState(s resolver.State) {
+	r.ccr.UpdateState(s)
+}
+
+const subConnCacheTime = time.Second * 10
+
+// lbCacheClientConn is a wrapper balancer.ClientConn with a SubConn cache.
+// SubConns will be kept in cache for subConnCacheTime before being removed.
+//
+// Its new and remove methods are updated to do cache first.
+type lbCacheClientConn struct {
+	cc      balancer.ClientConn
+	timeout time.Duration
+
+	mu sync.Mutex
+	// subConnCache only keeps subConns that are being deleted.
+	subConnCache  map[resolver.Address]*subConnCacheEntry
+	subConnToAddr map[balancer.SubConn]resolver.Address
+}
+
+type subConnCacheEntry struct {
+	sc balancer.SubConn
+
+	cancel        func()
+	abortDeleting bool
+}
+
+func newLBCacheClientConn(cc balancer.ClientConn) *lbCacheClientConn {
+	return &lbCacheClientConn{
+		cc:            cc,
+		timeout:       subConnCacheTime,
+		subConnCache:  make(map[resolver.Address]*subConnCacheEntry),
+		subConnToAddr: make(map[balancer.SubConn]resolver.Address),
+	}
+}
+
+func (ccc *lbCacheClientConn) NewSubConn(addrs []resolver.Address, opts balancer.NewSubConnOptions) (balancer.SubConn, error) {
+	if len(addrs) != 1 {
+		return nil, fmt.Errorf("grpclb calling NewSubConn with addrs of length %v", len(addrs))
+	}
+	addrWithoutMD := addrs[0]
+	addrWithoutMD.Metadata = nil
+
+	ccc.mu.Lock()
+	defer ccc.mu.Unlock()
+	if entry, ok := ccc.subConnCache[addrWithoutMD]; ok {
+		// If entry is in subConnCache, the SubConn was being deleted.
+		// cancel function will never be nil.
+		entry.cancel()
+		delete(ccc.subConnCache, addrWithoutMD)
+		return entry.sc, nil
+	}
+
+	scNew, err := ccc.cc.NewSubConn(addrs, opts)
+	if err != nil {
+		return nil, err
+	}
+
+	ccc.subConnToAddr[scNew] = addrWithoutMD
+	return scNew, nil
+}
+
+func (ccc *lbCacheClientConn) RemoveSubConn(sc balancer.SubConn) {
+	ccc.mu.Lock()
+	defer ccc.mu.Unlock()
+	addr, ok := ccc.subConnToAddr[sc]
+	if !ok {
+		return
+	}
+
+	if entry, ok := ccc.subConnCache[addr]; ok {
+		if entry.sc != sc {
+			// This could happen if NewSubConn was called multiple times for the
+			// same address, and those SubConns are all removed. We remove sc
+			// immediately here.
+			delete(ccc.subConnToAddr, sc)
+			ccc.cc.RemoveSubConn(sc)
+		}
+		return
+	}
+
+	entry := &subConnCacheEntry{
+		sc: sc,
+	}
+	ccc.subConnCache[addr] = entry
+
+	timer := time.AfterFunc(ccc.timeout, func() {
+		ccc.mu.Lock()
+		defer ccc.mu.Unlock()
+		if entry.abortDeleting {
+			return
+		}
+		ccc.cc.RemoveSubConn(sc)
+		delete(ccc.subConnToAddr, sc)
+		delete(ccc.subConnCache, addr)
+	})
+	entry.cancel = func() {
+		if !timer.Stop() {
+			// If stop was not successful, the timer has fired (this can only
+			// happen in a race). But the deleting function is blocked on ccc.mu
+			// because the mutex was held by the caller of this function.
+			//
+			// Set abortDeleting to true to abort the deleting function. When
+			// the lock is released, the deleting function will acquire the
+			// lock, check the value of abortDeleting and return.
+			entry.abortDeleting = true
+		}
+	}
+}
+
+func (ccc *lbCacheClientConn) UpdateState(s balancer.State) {
+	ccc.cc.UpdateState(s)
+}
+
+func (ccc *lbCacheClientConn) close() {
+	ccc.mu.Lock()
+	// Only cancel all existing timers. There's no need to remove SubConns.
+	for _, entry := range ccc.subConnCache {
+		entry.cancel()
+	}
+	ccc.mu.Unlock()
+}

+ 330 - 0
vendor/google.golang.org/grpc/credentials/alts/alts.go

@@ -0,0 +1,330 @@
+/*
+ *
+ * Copyright 2018 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Package alts implements the ALTS credential support by gRPC library, which
+// encapsulates all the state needed by a client to authenticate with a server
+// using ALTS and make various assertions, e.g., about the client's identity,
+// role, or whether it is authorized to make a particular call.
+// This package is experimental.
+package alts
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"net"
+	"sync"
+	"time"
+
+	"google.golang.org/grpc/credentials"
+	core "google.golang.org/grpc/credentials/alts/internal"
+	"google.golang.org/grpc/credentials/alts/internal/handshaker"
+	"google.golang.org/grpc/credentials/alts/internal/handshaker/service"
+	altspb "google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp"
+	"google.golang.org/grpc/grpclog"
+)
+
+const (
+	// hypervisorHandshakerServiceAddress represents the default ALTS gRPC
+	// handshaker service address in the hypervisor.
+	hypervisorHandshakerServiceAddress = "metadata.google.internal:8080"
+	// defaultTimeout specifies the server handshake timeout.
+	defaultTimeout = 30.0 * time.Second
+	// The following constants specify the minimum and maximum acceptable
+	// protocol versions.
+	protocolVersionMaxMajor = 2
+	protocolVersionMaxMinor = 1
+	protocolVersionMinMajor = 2
+	protocolVersionMinMinor = 1
+)
+
+var (
+	once          sync.Once
+	maxRPCVersion = &altspb.RpcProtocolVersions_Version{
+		Major: protocolVersionMaxMajor,
+		Minor: protocolVersionMaxMinor,
+	}
+	minRPCVersion = &altspb.RpcProtocolVersions_Version{
+		Major: protocolVersionMinMajor,
+		Minor: protocolVersionMinMinor,
+	}
+	// ErrUntrustedPlatform is returned from ClientHandshake and
+	// ServerHandshake is running on a platform where the trustworthiness of
+	// the handshaker service is not guaranteed.
+	ErrUntrustedPlatform = errors.New("ALTS: untrusted platform. ALTS is only supported on GCP")
+)
+
+// AuthInfo exposes security information from the ALTS handshake to the
+// application. This interface is to be implemented by ALTS. Users should not
+// need a brand new implementation of this interface. For situations like
+// testing, any new implementation should embed this interface. This allows
+// ALTS to add new methods to this interface.
+type AuthInfo interface {
+	// ApplicationProtocol returns application protocol negotiated for the
+	// ALTS connection.
+	ApplicationProtocol() string
+	// RecordProtocol returns the record protocol negotiated for the ALTS
+	// connection.
+	RecordProtocol() string
+	// SecurityLevel returns the security level of the created ALTS secure
+	// channel.
+	SecurityLevel() altspb.SecurityLevel
+	// PeerServiceAccount returns the peer service account.
+	PeerServiceAccount() string
+	// LocalServiceAccount returns the local service account.
+	LocalServiceAccount() string
+	// PeerRPCVersions returns the RPC version supported by the peer.
+	PeerRPCVersions() *altspb.RpcProtocolVersions
+}
+
+// ClientOptions contains the client-side options of an ALTS channel. These
+// options will be passed to the underlying ALTS handshaker.
+type ClientOptions struct {
+	// TargetServiceAccounts contains a list of expected target service
+	// accounts.
+	TargetServiceAccounts []string
+	// HandshakerServiceAddress represents the ALTS handshaker gRPC service
+	// address to connect to.
+	HandshakerServiceAddress string
+}
+
+// DefaultClientOptions creates a new ClientOptions object with the default
+// values.
+func DefaultClientOptions() *ClientOptions {
+	return &ClientOptions{
+		HandshakerServiceAddress: hypervisorHandshakerServiceAddress,
+	}
+}
+
+// ServerOptions contains the server-side options of an ALTS channel. These
+// options will be passed to the underlying ALTS handshaker.
+type ServerOptions struct {
+	// HandshakerServiceAddress represents the ALTS handshaker gRPC service
+	// address to connect to.
+	HandshakerServiceAddress string
+}
+
+// DefaultServerOptions creates a new ServerOptions object with the default
+// values.
+func DefaultServerOptions() *ServerOptions {
+	return &ServerOptions{
+		HandshakerServiceAddress: hypervisorHandshakerServiceAddress,
+	}
+}
+
+// altsTC is the credentials required for authenticating a connection using ALTS.
+// It implements credentials.TransportCredentials interface.
+type altsTC struct {
+	info      *credentials.ProtocolInfo
+	side      core.Side
+	accounts  []string
+	hsAddress string
+}
+
+// NewClientCreds constructs a client-side ALTS TransportCredentials object.
+func NewClientCreds(opts *ClientOptions) credentials.TransportCredentials {
+	return newALTS(core.ClientSide, opts.TargetServiceAccounts, opts.HandshakerServiceAddress)
+}
+
+// NewServerCreds constructs a server-side ALTS TransportCredentials object.
+func NewServerCreds(opts *ServerOptions) credentials.TransportCredentials {
+	return newALTS(core.ServerSide, nil, opts.HandshakerServiceAddress)
+}
+
+func newALTS(side core.Side, accounts []string, hsAddress string) credentials.TransportCredentials {
+	once.Do(func() {
+		vmOnGCP = isRunningOnGCP()
+	})
+
+	if hsAddress == "" {
+		hsAddress = hypervisorHandshakerServiceAddress
+	}
+	return &altsTC{
+		info: &credentials.ProtocolInfo{
+			SecurityProtocol: "alts",
+			SecurityVersion:  "1.0",
+		},
+		side:      side,
+		accounts:  accounts,
+		hsAddress: hsAddress,
+	}
+}
+
+// ClientHandshake implements the client side handshake protocol.
+func (g *altsTC) ClientHandshake(ctx context.Context, addr string, rawConn net.Conn) (_ net.Conn, _ credentials.AuthInfo, err error) {
+	if !vmOnGCP {
+		return nil, nil, ErrUntrustedPlatform
+	}
+
+	// Connecting to ALTS handshaker service.
+	hsConn, err := service.Dial(g.hsAddress)
+	if err != nil {
+		return nil, nil, err
+	}
+	// Do not close hsConn since it is shared with other handshakes.
+
+	// Possible context leak:
+	// The cancel function for the child context we create will only be
+	// called a non-nil error is returned.
+	var cancel context.CancelFunc
+	ctx, cancel = context.WithCancel(ctx)
+	defer func() {
+		if err != nil {
+			cancel()
+		}
+	}()
+
+	opts := handshaker.DefaultClientHandshakerOptions()
+	opts.TargetName = addr
+	opts.TargetServiceAccounts = g.accounts
+	opts.RPCVersions = &altspb.RpcProtocolVersions{
+		MaxRpcVersion: maxRPCVersion,
+		MinRpcVersion: minRPCVersion,
+	}
+	chs, err := handshaker.NewClientHandshaker(ctx, hsConn, rawConn, opts)
+	if err != nil {
+		return nil, nil, err
+	}
+	defer func() {
+		if err != nil {
+			chs.Close()
+		}
+	}()
+	secConn, authInfo, err := chs.ClientHandshake(ctx)
+	if err != nil {
+		return nil, nil, err
+	}
+	altsAuthInfo, ok := authInfo.(AuthInfo)
+	if !ok {
+		return nil, nil, errors.New("client-side auth info is not of type alts.AuthInfo")
+	}
+	match, _ := checkRPCVersions(opts.RPCVersions, altsAuthInfo.PeerRPCVersions())
+	if !match {
+		return nil, nil, fmt.Errorf("server-side RPC versions are not compatible with this client, local versions: %v, peer versions: %v", opts.RPCVersions, altsAuthInfo.PeerRPCVersions())
+	}
+	return secConn, authInfo, nil
+}
+
+// ServerHandshake implements the server side ALTS handshaker.
+func (g *altsTC) ServerHandshake(rawConn net.Conn) (_ net.Conn, _ credentials.AuthInfo, err error) {
+	if !vmOnGCP {
+		return nil, nil, ErrUntrustedPlatform
+	}
+	// Connecting to ALTS handshaker service.
+	hsConn, err := service.Dial(g.hsAddress)
+	if err != nil {
+		return nil, nil, err
+	}
+	// Do not close hsConn since it's shared with other handshakes.
+
+	ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
+	defer cancel()
+	opts := handshaker.DefaultServerHandshakerOptions()
+	opts.RPCVersions = &altspb.RpcProtocolVersions{
+		MaxRpcVersion: maxRPCVersion,
+		MinRpcVersion: minRPCVersion,
+	}
+	shs, err := handshaker.NewServerHandshaker(ctx, hsConn, rawConn, opts)
+	if err != nil {
+		return nil, nil, err
+	}
+	defer func() {
+		if err != nil {
+			shs.Close()
+		}
+	}()
+	secConn, authInfo, err := shs.ServerHandshake(ctx)
+	if err != nil {
+		return nil, nil, err
+	}
+	altsAuthInfo, ok := authInfo.(AuthInfo)
+	if !ok {
+		return nil, nil, errors.New("server-side auth info is not of type alts.AuthInfo")
+	}
+	match, _ := checkRPCVersions(opts.RPCVersions, altsAuthInfo.PeerRPCVersions())
+	if !match {
+		return nil, nil, fmt.Errorf("client-side RPC versions is not compatible with this server, local versions: %v, peer versions: %v", opts.RPCVersions, altsAuthInfo.PeerRPCVersions())
+	}
+	return secConn, authInfo, nil
+}
+
+func (g *altsTC) Info() credentials.ProtocolInfo {
+	return *g.info
+}
+
+func (g *altsTC) Clone() credentials.TransportCredentials {
+	info := *g.info
+	var accounts []string
+	if g.accounts != nil {
+		accounts = make([]string, len(g.accounts))
+		copy(accounts, g.accounts)
+	}
+	return &altsTC{
+		info:      &info,
+		side:      g.side,
+		hsAddress: g.hsAddress,
+		accounts:  accounts,
+	}
+}
+
+func (g *altsTC) OverrideServerName(serverNameOverride string) error {
+	g.info.ServerName = serverNameOverride
+	return nil
+}
+
+// compareRPCVersion returns 0 if v1 == v2, 1 if v1 > v2 and -1 if v1 < v2.
+func compareRPCVersions(v1, v2 *altspb.RpcProtocolVersions_Version) int {
+	switch {
+	case v1.GetMajor() > v2.GetMajor(),
+		v1.GetMajor() == v2.GetMajor() && v1.GetMinor() > v2.GetMinor():
+		return 1
+	case v1.GetMajor() < v2.GetMajor(),
+		v1.GetMajor() == v2.GetMajor() && v1.GetMinor() < v2.GetMinor():
+		return -1
+	}
+	return 0
+}
+
+// checkRPCVersions performs a version check between local and peer rpc protocol
+// versions. This function returns true if the check passes which means both
+// parties agreed on a common rpc protocol to use, and false otherwise. The
+// function also returns the highest common RPC protocol version both parties
+// agreed on.
+func checkRPCVersions(local, peer *altspb.RpcProtocolVersions) (bool, *altspb.RpcProtocolVersions_Version) {
+	if local == nil || peer == nil {
+		grpclog.Error("invalid checkRPCVersions argument, either local or peer is nil.")
+		return false, nil
+	}
+
+	// maxCommonVersion is MIN(local.max, peer.max).
+	maxCommonVersion := local.GetMaxRpcVersion()
+	if compareRPCVersions(local.GetMaxRpcVersion(), peer.GetMaxRpcVersion()) > 0 {
+		maxCommonVersion = peer.GetMaxRpcVersion()
+	}
+
+	// minCommonVersion is MAX(local.min, peer.min).
+	minCommonVersion := peer.GetMinRpcVersion()
+	if compareRPCVersions(local.GetMinRpcVersion(), peer.GetMinRpcVersion()) > 0 {
+		minCommonVersion = local.GetMinRpcVersion()
+	}
+
+	if compareRPCVersions(maxCommonVersion, minCommonVersion) < 0 {
+		return false, nil
+	}
+	return true, maxCommonVersion
+}

+ 89 - 0
vendor/google.golang.org/grpc/credentials/alts/internal/authinfo/authinfo.go

@@ -0,0 +1,89 @@
+/*
+ *
+ * Copyright 2018 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Package authinfo provide authentication information returned by handshakers.
+package authinfo
+
+import (
+	"google.golang.org/grpc/credentials"
+	altspb "google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp"
+)
+
+var _ credentials.AuthInfo = (*altsAuthInfo)(nil)
+
+// altsAuthInfo exposes security information from the ALTS handshake to the
+// application. altsAuthInfo is immutable and implements credentials.AuthInfo.
+type altsAuthInfo struct {
+	p *altspb.AltsContext
+	credentials.CommonAuthInfo
+}
+
+// New returns a new altsAuthInfo object given handshaker results.
+func New(result *altspb.HandshakerResult) credentials.AuthInfo {
+	return newAuthInfo(result)
+}
+
+func newAuthInfo(result *altspb.HandshakerResult) *altsAuthInfo {
+	return &altsAuthInfo{
+		p: &altspb.AltsContext{
+			ApplicationProtocol: result.GetApplicationProtocol(),
+			RecordProtocol:      result.GetRecordProtocol(),
+			// TODO: assign security level from result.
+			SecurityLevel:       altspb.SecurityLevel_INTEGRITY_AND_PRIVACY,
+			PeerServiceAccount:  result.GetPeerIdentity().GetServiceAccount(),
+			LocalServiceAccount: result.GetLocalIdentity().GetServiceAccount(),
+			PeerRpcVersions:     result.GetPeerRpcVersions(),
+		},
+		CommonAuthInfo: credentials.CommonAuthInfo{SecurityLevel: credentials.PrivacyAndIntegrity},
+	}
+}
+
+// AuthType identifies the context as providing ALTS authentication information.
+func (s *altsAuthInfo) AuthType() string {
+	return "alts"
+}
+
+// ApplicationProtocol returns the context's application protocol.
+func (s *altsAuthInfo) ApplicationProtocol() string {
+	return s.p.GetApplicationProtocol()
+}
+
+// RecordProtocol returns the context's record protocol.
+func (s *altsAuthInfo) RecordProtocol() string {
+	return s.p.GetRecordProtocol()
+}
+
+// SecurityLevel returns the context's security level.
+func (s *altsAuthInfo) SecurityLevel() altspb.SecurityLevel {
+	return s.p.GetSecurityLevel()
+}
+
+// PeerServiceAccount returns the context's peer service account.
+func (s *altsAuthInfo) PeerServiceAccount() string {
+	return s.p.GetPeerServiceAccount()
+}
+
+// LocalServiceAccount returns the context's local service account.
+func (s *altsAuthInfo) LocalServiceAccount() string {
+	return s.p.GetLocalServiceAccount()
+}
+
+// PeerRPCVersions returns the context's peer RPC versions.
+func (s *altsAuthInfo) PeerRPCVersions() *altspb.RpcProtocolVersions {
+	return s.p.GetPeerRpcVersions()
+}

+ 69 - 0
vendor/google.golang.org/grpc/credentials/alts/internal/common.go

@@ -0,0 +1,69 @@
+/*
+ *
+ * Copyright 2018 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+//go:generate ./regenerate.sh
+
+// Package internal contains common core functionality for ALTS.
+package internal
+
+import (
+	"context"
+	"net"
+
+	"google.golang.org/grpc/credentials"
+)
+
+const (
+	// ClientSide identifies the client in this communication.
+	ClientSide Side = iota
+	// ServerSide identifies the server in this communication.
+	ServerSide
+)
+
+// PeerNotRespondingError is returned when a peer server is not responding
+// after a channel has been established. It is treated as a temporary connection
+// error and re-connection to the server should be attempted.
+var PeerNotRespondingError = &peerNotRespondingError{}
+
+// Side identifies the party's role: client or server.
+type Side int
+
+type peerNotRespondingError struct{}
+
+// Return an error message for the purpose of logging.
+func (e *peerNotRespondingError) Error() string {
+	return "peer server is not responding and re-connection should be attempted."
+}
+
+// Temporary indicates if this connection error is temporary or fatal.
+func (e *peerNotRespondingError) Temporary() bool {
+	return true
+}
+
+// Handshaker defines a ALTS handshaker interface.
+type Handshaker interface {
+	// ClientHandshake starts and completes a client-side handshaking and
+	// returns a secure connection and corresponding auth information.
+	ClientHandshake(ctx context.Context) (net.Conn, credentials.AuthInfo, error)
+	// ServerHandshake starts and completes a server-side handshaking and
+	// returns a secure connection and corresponding auth information.
+	ServerHandshake(ctx context.Context) (net.Conn, credentials.AuthInfo, error)
+	// Close terminates the Handshaker. It should be called when the caller
+	// obtains the secure connection.
+	Close()
+}

+ 131 - 0
vendor/google.golang.org/grpc/credentials/alts/internal/conn/aeadrekey.go

@@ -0,0 +1,131 @@
+/*
+ *
+ * Copyright 2018 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package conn
+
+import (
+	"bytes"
+	"crypto/aes"
+	"crypto/cipher"
+	"crypto/hmac"
+	"crypto/sha256"
+	"encoding/binary"
+	"fmt"
+	"strconv"
+)
+
+// rekeyAEAD holds the necessary information for an AEAD based on
+// AES-GCM that performs nonce-based key derivation and XORs the
+// nonce with a random mask.
+type rekeyAEAD struct {
+	kdfKey     []byte
+	kdfCounter []byte
+	nonceMask  []byte
+	nonceBuf   []byte
+	gcmAEAD    cipher.AEAD
+}
+
+// KeySizeError signals that the given key does not have the correct size.
+type KeySizeError int
+
+func (k KeySizeError) Error() string {
+	return "alts/conn: invalid key size " + strconv.Itoa(int(k))
+}
+
+// newRekeyAEAD creates a new instance of aes128gcm with rekeying.
+// The key argument should be 44 bytes, the first 32 bytes are used as a key
+// for HKDF-expand and the remainining 12 bytes are used as a random mask for
+// the counter.
+func newRekeyAEAD(key []byte) (*rekeyAEAD, error) {
+	k := len(key)
+	if k != kdfKeyLen+nonceLen {
+		return nil, KeySizeError(k)
+	}
+	return &rekeyAEAD{
+		kdfKey:     key[:kdfKeyLen],
+		kdfCounter: make([]byte, kdfCounterLen),
+		nonceMask:  key[kdfKeyLen:],
+		nonceBuf:   make([]byte, nonceLen),
+		gcmAEAD:    nil,
+	}, nil
+}
+
+// Seal rekeys if nonce[2:8] is different than in the last call, masks the nonce,
+// and calls Seal for aes128gcm.
+func (s *rekeyAEAD) Seal(dst, nonce, plaintext, additionalData []byte) []byte {
+	if err := s.rekeyIfRequired(nonce); err != nil {
+		panic(fmt.Sprintf("Rekeying failed with: %s", err.Error()))
+	}
+	maskNonce(s.nonceBuf, nonce, s.nonceMask)
+	return s.gcmAEAD.Seal(dst, s.nonceBuf, plaintext, additionalData)
+}
+
+// Open rekeys if nonce[2:8] is different than in the last call, masks the nonce,
+// and calls Open for aes128gcm.
+func (s *rekeyAEAD) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {
+	if err := s.rekeyIfRequired(nonce); err != nil {
+		return nil, err
+	}
+	maskNonce(s.nonceBuf, nonce, s.nonceMask)
+	return s.gcmAEAD.Open(dst, s.nonceBuf, ciphertext, additionalData)
+}
+
+// rekeyIfRequired creates a new aes128gcm AEAD if the existing AEAD is nil
+// or cannot be used with given nonce.
+func (s *rekeyAEAD) rekeyIfRequired(nonce []byte) error {
+	newKdfCounter := nonce[kdfCounterOffset : kdfCounterOffset+kdfCounterLen]
+	if s.gcmAEAD != nil && bytes.Equal(newKdfCounter, s.kdfCounter) {
+		return nil
+	}
+	copy(s.kdfCounter, newKdfCounter)
+	a, err := aes.NewCipher(hkdfExpand(s.kdfKey, s.kdfCounter))
+	if err != nil {
+		return err
+	}
+	s.gcmAEAD, err = cipher.NewGCM(a)
+	return err
+}
+
+// maskNonce XORs the given nonce with the mask and stores the result in dst.
+func maskNonce(dst, nonce, mask []byte) {
+	nonce1 := binary.LittleEndian.Uint64(nonce[:sizeUint64])
+	nonce2 := binary.LittleEndian.Uint32(nonce[sizeUint64:])
+	mask1 := binary.LittleEndian.Uint64(mask[:sizeUint64])
+	mask2 := binary.LittleEndian.Uint32(mask[sizeUint64:])
+	binary.LittleEndian.PutUint64(dst[:sizeUint64], nonce1^mask1)
+	binary.LittleEndian.PutUint32(dst[sizeUint64:], nonce2^mask2)
+}
+
+// NonceSize returns the required nonce size.
+func (s *rekeyAEAD) NonceSize() int {
+	return s.gcmAEAD.NonceSize()
+}
+
+// Overhead returns the ciphertext overhead.
+func (s *rekeyAEAD) Overhead() int {
+	return s.gcmAEAD.Overhead()
+}
+
+// hkdfExpand computes the first 16 bytes of the HKDF-expand function
+// defined in RFC5869.
+func hkdfExpand(key, info []byte) []byte {
+	mac := hmac.New(sha256.New, key)
+	mac.Write(info)
+	mac.Write([]byte{0x01}[:])
+	return mac.Sum(nil)[:aeadKeyLen]
+}

+ 105 - 0
vendor/google.golang.org/grpc/credentials/alts/internal/conn/aes128gcm.go

@@ -0,0 +1,105 @@
+/*
+ *
+ * Copyright 2018 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package conn
+
+import (
+	"crypto/aes"
+	"crypto/cipher"
+
+	core "google.golang.org/grpc/credentials/alts/internal"
+)
+
+const (
+	// Overflow length n in bytes, never encrypt more than 2^(n*8) frames (in
+	// each direction).
+	overflowLenAES128GCM = 5
+)
+
+// aes128gcm is the struct that holds necessary information for ALTS record.
+// The counter value is NOT included in the payload during the encryption and
+// decryption operations.
+type aes128gcm struct {
+	// inCounter is used in ALTS record to check that incoming counters are
+	// as expected, since ALTS record guarantees that messages are unwrapped
+	// in the same order that the peer wrapped them.
+	inCounter  Counter
+	outCounter Counter
+	aead       cipher.AEAD
+}
+
+// NewAES128GCM creates an instance that uses aes128gcm for ALTS record.
+func NewAES128GCM(side core.Side, key []byte) (ALTSRecordCrypto, error) {
+	c, err := aes.NewCipher(key)
+	if err != nil {
+		return nil, err
+	}
+	a, err := cipher.NewGCM(c)
+	if err != nil {
+		return nil, err
+	}
+	return &aes128gcm{
+		inCounter:  NewInCounter(side, overflowLenAES128GCM),
+		outCounter: NewOutCounter(side, overflowLenAES128GCM),
+		aead:       a,
+	}, nil
+}
+
+// Encrypt is the encryption function. dst can contain bytes at the beginning of
+// the ciphertext that will not be encrypted but will be authenticated. If dst
+// has enough capacity to hold these bytes, the ciphertext and the tag, no
+// allocation and copy operations will be performed. dst and plaintext do not
+// overlap.
+func (s *aes128gcm) Encrypt(dst, plaintext []byte) ([]byte, error) {
+	// If we need to allocate an output buffer, we want to include space for
+	// GCM tag to avoid forcing ALTS record to reallocate as well.
+	dlen := len(dst)
+	dst, out := SliceForAppend(dst, len(plaintext)+GcmTagSize)
+	seq, err := s.outCounter.Value()
+	if err != nil {
+		return nil, err
+	}
+	data := out[:len(plaintext)]
+	copy(data, plaintext) // data may alias plaintext
+
+	// Seal appends the ciphertext and the tag to its first argument and
+	// returns the updated slice. However, SliceForAppend above ensures that
+	// dst has enough capacity to avoid a reallocation and copy due to the
+	// append.
+	dst = s.aead.Seal(dst[:dlen], seq, data, nil)
+	s.outCounter.Inc()
+	return dst, nil
+}
+
+func (s *aes128gcm) EncryptionOverhead() int {
+	return GcmTagSize
+}
+
+func (s *aes128gcm) Decrypt(dst, ciphertext []byte) ([]byte, error) {
+	seq, err := s.inCounter.Value()
+	if err != nil {
+		return nil, err
+	}
+	// If dst is equal to ciphertext[:0], ciphertext storage is reused.
+	plaintext, err := s.aead.Open(dst, seq, ciphertext, nil)
+	if err != nil {
+		return nil, ErrAuth
+	}
+	s.inCounter.Inc()
+	return plaintext, nil
+}

+ 116 - 0
vendor/google.golang.org/grpc/credentials/alts/internal/conn/aes128gcmrekey.go

@@ -0,0 +1,116 @@
+/*
+ *
+ * Copyright 2018 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package conn
+
+import (
+	"crypto/cipher"
+
+	core "google.golang.org/grpc/credentials/alts/internal"
+)
+
+const (
+	// Overflow length n in bytes, never encrypt more than 2^(n*8) frames (in
+	// each direction).
+	overflowLenAES128GCMRekey = 8
+	nonceLen                  = 12
+	aeadKeyLen                = 16
+	kdfKeyLen                 = 32
+	kdfCounterOffset          = 2
+	kdfCounterLen             = 6
+	sizeUint64                = 8
+)
+
+// aes128gcmRekey is the struct that holds necessary information for ALTS record.
+// The counter value is NOT included in the payload during the encryption and
+// decryption operations.
+type aes128gcmRekey struct {
+	// inCounter is used in ALTS record to check that incoming counters are
+	// as expected, since ALTS record guarantees that messages are unwrapped
+	// in the same order that the peer wrapped them.
+	inCounter  Counter
+	outCounter Counter
+	inAEAD     cipher.AEAD
+	outAEAD    cipher.AEAD
+}
+
+// NewAES128GCMRekey creates an instance that uses aes128gcm with rekeying
+// for ALTS record. The key argument should be 44 bytes, the first 32 bytes
+// are used as a key for HKDF-expand and the remainining 12 bytes are used
+// as a random mask for the counter.
+func NewAES128GCMRekey(side core.Side, key []byte) (ALTSRecordCrypto, error) {
+	inCounter := NewInCounter(side, overflowLenAES128GCMRekey)
+	outCounter := NewOutCounter(side, overflowLenAES128GCMRekey)
+	inAEAD, err := newRekeyAEAD(key)
+	if err != nil {
+		return nil, err
+	}
+	outAEAD, err := newRekeyAEAD(key)
+	if err != nil {
+		return nil, err
+	}
+	return &aes128gcmRekey{
+		inCounter,
+		outCounter,
+		inAEAD,
+		outAEAD,
+	}, nil
+}
+
+// Encrypt is the encryption function. dst can contain bytes at the beginning of
+// the ciphertext that will not be encrypted but will be authenticated. If dst
+// has enough capacity to hold these bytes, the ciphertext and the tag, no
+// allocation and copy operations will be performed. dst and plaintext do not
+// overlap.
+func (s *aes128gcmRekey) Encrypt(dst, plaintext []byte) ([]byte, error) {
+	// If we need to allocate an output buffer, we want to include space for
+	// GCM tag to avoid forcing ALTS record to reallocate as well.
+	dlen := len(dst)
+	dst, out := SliceForAppend(dst, len(plaintext)+GcmTagSize)
+	seq, err := s.outCounter.Value()
+	if err != nil {
+		return nil, err
+	}
+	data := out[:len(plaintext)]
+	copy(data, plaintext) // data may alias plaintext
+
+	// Seal appends the ciphertext and the tag to its first argument and
+	// returns the updated slice. However, SliceForAppend above ensures that
+	// dst has enough capacity to avoid a reallocation and copy due to the
+	// append.
+	dst = s.outAEAD.Seal(dst[:dlen], seq, data, nil)
+	s.outCounter.Inc()
+	return dst, nil
+}
+
+func (s *aes128gcmRekey) EncryptionOverhead() int {
+	return GcmTagSize
+}
+
+func (s *aes128gcmRekey) Decrypt(dst, ciphertext []byte) ([]byte, error) {
+	seq, err := s.inCounter.Value()
+	if err != nil {
+		return nil, err
+	}
+	plaintext, err := s.inAEAD.Open(dst, seq, ciphertext, nil)
+	if err != nil {
+		return nil, ErrAuth
+	}
+	s.inCounter.Inc()
+	return plaintext, nil
+}

+ 70 - 0
vendor/google.golang.org/grpc/credentials/alts/internal/conn/common.go

@@ -0,0 +1,70 @@
+/*
+ *
+ * Copyright 2018 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package conn
+
+import (
+	"encoding/binary"
+	"errors"
+	"fmt"
+)
+
+const (
+	// GcmTagSize is the GCM tag size is the difference in length between
+	// plaintext and ciphertext. From crypto/cipher/gcm.go in Go crypto
+	// library.
+	GcmTagSize = 16
+)
+
+// ErrAuth occurs on authentication failure.
+var ErrAuth = errors.New("message authentication failed")
+
+// SliceForAppend takes a slice and a requested number of bytes. It returns a
+// slice with the contents of the given slice followed by that many bytes and a
+// second slice that aliases into it and contains only the extra bytes. If the
+// original slice has sufficient capacity then no allocation is performed.
+func SliceForAppend(in []byte, n int) (head, tail []byte) {
+	if total := len(in) + n; cap(in) >= total {
+		head = in[:total]
+	} else {
+		head = make([]byte, total)
+		copy(head, in)
+	}
+	tail = head[len(in):]
+	return head, tail
+}
+
+// ParseFramedMsg parse the provided buffer and returns a frame of the format
+// msgLength+msg and any remaining bytes in that buffer.
+func ParseFramedMsg(b []byte, maxLen uint32) ([]byte, []byte, error) {
+	// If the size field is not complete, return the provided buffer as
+	// remaining buffer.
+	if len(b) < MsgLenFieldSize {
+		return nil, b, nil
+	}
+	msgLenField := b[:MsgLenFieldSize]
+	length := binary.LittleEndian.Uint32(msgLenField)
+	if length > maxLen {
+		return nil, nil, fmt.Errorf("received the frame length %d larger than the limit %d", length, maxLen)
+	}
+	if len(b) < int(length)+4 { // account for the first 4 msg length bytes.
+		// Frame is not complete yet.
+		return nil, b, nil
+	}
+	return b[:MsgLenFieldSize+length], b[MsgLenFieldSize+length:], nil
+}

+ 62 - 0
vendor/google.golang.org/grpc/credentials/alts/internal/conn/counter.go

@@ -0,0 +1,62 @@
+/*
+ *
+ * Copyright 2018 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package conn
+
+import (
+	"errors"
+)
+
+const counterLen = 12
+
+var (
+	errInvalidCounter = errors.New("invalid counter")
+)
+
+// Counter is a 96-bit, little-endian counter.
+type Counter struct {
+	value       [counterLen]byte
+	invalid     bool
+	overflowLen int
+}
+
+// Value returns the current value of the counter as a byte slice.
+func (c *Counter) Value() ([]byte, error) {
+	if c.invalid {
+		return nil, errInvalidCounter
+	}
+	return c.value[:], nil
+}
+
+// Inc increments the counter and checks for overflow.
+func (c *Counter) Inc() {
+	// If the counter is already invalid, there is no need to increase it.
+	if c.invalid {
+		return
+	}
+	i := 0
+	for ; i < c.overflowLen; i++ {
+		c.value[i]++
+		if c.value[i] != 0 {
+			break
+		}
+	}
+	if i == c.overflowLen {
+		c.invalid = true
+	}
+}

+ 271 - 0
vendor/google.golang.org/grpc/credentials/alts/internal/conn/record.go

@@ -0,0 +1,271 @@
+/*
+ *
+ * Copyright 2018 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Package conn contains an implementation of a secure channel created by gRPC
+// handshakers.
+package conn
+
+import (
+	"encoding/binary"
+	"fmt"
+	"math"
+	"net"
+
+	core "google.golang.org/grpc/credentials/alts/internal"
+)
+
+// ALTSRecordCrypto is the interface for gRPC ALTS record protocol.
+type ALTSRecordCrypto interface {
+	// Encrypt encrypts the plaintext and computes the tag (if any) of dst
+	// and plaintext, dst and plaintext do not overlap.
+	Encrypt(dst, plaintext []byte) ([]byte, error)
+	// EncryptionOverhead returns the tag size (if any) in bytes.
+	EncryptionOverhead() int
+	// Decrypt decrypts ciphertext and verify the tag (if any). dst and
+	// ciphertext may alias exactly or not at all. To reuse ciphertext's
+	// storage for the decrypted output, use ciphertext[:0] as dst.
+	Decrypt(dst, ciphertext []byte) ([]byte, error)
+}
+
+// ALTSRecordFunc is a function type for factory functions that create
+// ALTSRecordCrypto instances.
+type ALTSRecordFunc func(s core.Side, keyData []byte) (ALTSRecordCrypto, error)
+
+const (
+	// MsgLenFieldSize is the byte size of the frame length field of a
+	// framed message.
+	MsgLenFieldSize = 4
+	// The byte size of the message type field of a framed message.
+	msgTypeFieldSize = 4
+	// The bytes size limit for a ALTS record message.
+	altsRecordLengthLimit = 1024 * 1024 // 1 MiB
+	// The default bytes size of a ALTS record message.
+	altsRecordDefaultLength = 4 * 1024 // 4KiB
+	// Message type value included in ALTS record framing.
+	altsRecordMsgType = uint32(0x06)
+	// The initial write buffer size.
+	altsWriteBufferInitialSize = 32 * 1024 // 32KiB
+	// The maximum write buffer size. This *must* be multiple of
+	// altsRecordDefaultLength.
+	altsWriteBufferMaxSize = 512 * 1024 // 512KiB
+)
+
+var (
+	protocols = make(map[string]ALTSRecordFunc)
+)
+
+// RegisterProtocol register a ALTS record encryption protocol.
+func RegisterProtocol(protocol string, f ALTSRecordFunc) error {
+	if _, ok := protocols[protocol]; ok {
+		return fmt.Errorf("protocol %v is already registered", protocol)
+	}
+	protocols[protocol] = f
+	return nil
+}
+
+// conn represents a secured connection. It implements the net.Conn interface.
+type conn struct {
+	net.Conn
+	crypto ALTSRecordCrypto
+	// buf holds data that has been read from the connection and decrypted,
+	// but has not yet been returned by Read.
+	buf                []byte
+	payloadLengthLimit int
+	// protected holds data read from the network but have not yet been
+	// decrypted. This data might not compose a complete frame.
+	protected []byte
+	// writeBuf is a buffer used to contain encrypted frames before being
+	// written to the network.
+	writeBuf []byte
+	// nextFrame stores the next frame (in protected buffer) info.
+	nextFrame []byte
+	// overhead is the calculated overhead of each frame.
+	overhead int
+}
+
+// NewConn creates a new secure channel instance given the other party role and
+// handshaking result.
+func NewConn(c net.Conn, side core.Side, recordProtocol string, key []byte, protected []byte) (net.Conn, error) {
+	newCrypto := protocols[recordProtocol]
+	if newCrypto == nil {
+		return nil, fmt.Errorf("negotiated unknown next_protocol %q", recordProtocol)
+	}
+	crypto, err := newCrypto(side, key)
+	if err != nil {
+		return nil, fmt.Errorf("protocol %q: %v", recordProtocol, err)
+	}
+	overhead := MsgLenFieldSize + msgTypeFieldSize + crypto.EncryptionOverhead()
+	payloadLengthLimit := altsRecordDefaultLength - overhead
+	if protected == nil {
+		// We pre-allocate protected to be of size
+		// 2*altsRecordDefaultLength-1 during initialization. We only
+		// read from the network into protected when protected does not
+		// contain a complete frame, which is at most
+		// altsRecordDefaultLength-1 (bytes). And we read at most
+		// altsRecordDefaultLength (bytes) data into protected at one
+		// time. Therefore, 2*altsRecordDefaultLength-1 is large enough
+		// to buffer data read from the network.
+		protected = make([]byte, 0, 2*altsRecordDefaultLength-1)
+	}
+
+	altsConn := &conn{
+		Conn:               c,
+		crypto:             crypto,
+		payloadLengthLimit: payloadLengthLimit,
+		protected:          protected,
+		writeBuf:           make([]byte, altsWriteBufferInitialSize),
+		nextFrame:          protected,
+		overhead:           overhead,
+	}
+	return altsConn, nil
+}
+
+// Read reads and decrypts a frame from the underlying connection, and copies the
+// decrypted payload into b. If the size of the payload is greater than len(b),
+// Read retains the remaining bytes in an internal buffer, and subsequent calls
+// to Read will read from this buffer until it is exhausted.
+func (p *conn) Read(b []byte) (n int, err error) {
+	if len(p.buf) == 0 {
+		var framedMsg []byte
+		framedMsg, p.nextFrame, err = ParseFramedMsg(p.nextFrame, altsRecordLengthLimit)
+		if err != nil {
+			return n, err
+		}
+		// Check whether the next frame to be decrypted has been
+		// completely received yet.
+		if len(framedMsg) == 0 {
+			copy(p.protected, p.nextFrame)
+			p.protected = p.protected[:len(p.nextFrame)]
+			// Always copy next incomplete frame to the beginning of
+			// the protected buffer and reset nextFrame to it.
+			p.nextFrame = p.protected
+		}
+		// Check whether a complete frame has been received yet.
+		for len(framedMsg) == 0 {
+			if len(p.protected) == cap(p.protected) {
+				tmp := make([]byte, len(p.protected), cap(p.protected)+altsRecordDefaultLength)
+				copy(tmp, p.protected)
+				p.protected = tmp
+			}
+			n, err = p.Conn.Read(p.protected[len(p.protected):min(cap(p.protected), len(p.protected)+altsRecordDefaultLength)])
+			if err != nil {
+				return 0, err
+			}
+			p.protected = p.protected[:len(p.protected)+n]
+			framedMsg, p.nextFrame, err = ParseFramedMsg(p.protected, altsRecordLengthLimit)
+			if err != nil {
+				return 0, err
+			}
+		}
+		// Now we have a complete frame, decrypted it.
+		msg := framedMsg[MsgLenFieldSize:]
+		msgType := binary.LittleEndian.Uint32(msg[:msgTypeFieldSize])
+		if msgType&0xff != altsRecordMsgType {
+			return 0, fmt.Errorf("received frame with incorrect message type %v, expected lower byte %v",
+				msgType, altsRecordMsgType)
+		}
+		ciphertext := msg[msgTypeFieldSize:]
+
+		// Decrypt requires that if the dst and ciphertext alias, they
+		// must alias exactly. Code here used to use msg[:0], but msg
+		// starts MsgLenFieldSize+msgTypeFieldSize bytes earlier than
+		// ciphertext, so they alias inexactly. Using ciphertext[:0]
+		// arranges the appropriate aliasing without needing to copy
+		// ciphertext or use a separate destination buffer. For more info
+		// check: https://golang.org/pkg/crypto/cipher/#AEAD.
+		p.buf, err = p.crypto.Decrypt(ciphertext[:0], ciphertext)
+		if err != nil {
+			return 0, err
+		}
+	}
+
+	n = copy(b, p.buf)
+	p.buf = p.buf[n:]
+	return n, nil
+}
+
+// Write encrypts, frames, and writes bytes from b to the underlying connection.
+func (p *conn) Write(b []byte) (n int, err error) {
+	n = len(b)
+	// Calculate the output buffer size with framing and encryption overhead.
+	numOfFrames := int(math.Ceil(float64(len(b)) / float64(p.payloadLengthLimit)))
+	size := len(b) + numOfFrames*p.overhead
+	// If writeBuf is too small, increase its size up to the maximum size.
+	partialBSize := len(b)
+	if size > altsWriteBufferMaxSize {
+		size = altsWriteBufferMaxSize
+		const numOfFramesInMaxWriteBuf = altsWriteBufferMaxSize / altsRecordDefaultLength
+		partialBSize = numOfFramesInMaxWriteBuf * p.payloadLengthLimit
+	}
+	if len(p.writeBuf) < size {
+		p.writeBuf = make([]byte, size)
+	}
+
+	for partialBStart := 0; partialBStart < len(b); partialBStart += partialBSize {
+		partialBEnd := partialBStart + partialBSize
+		if partialBEnd > len(b) {
+			partialBEnd = len(b)
+		}
+		partialB := b[partialBStart:partialBEnd]
+		writeBufIndex := 0
+		for len(partialB) > 0 {
+			payloadLen := len(partialB)
+			if payloadLen > p.payloadLengthLimit {
+				payloadLen = p.payloadLengthLimit
+			}
+			buf := partialB[:payloadLen]
+			partialB = partialB[payloadLen:]
+
+			// Write buffer contains: length, type, payload, and tag
+			// if any.
+
+			// 1. Fill in type field.
+			msg := p.writeBuf[writeBufIndex+MsgLenFieldSize:]
+			binary.LittleEndian.PutUint32(msg, altsRecordMsgType)
+
+			// 2. Encrypt the payload and create a tag if any.
+			msg, err = p.crypto.Encrypt(msg[:msgTypeFieldSize], buf)
+			if err != nil {
+				return n, err
+			}
+
+			// 3. Fill in the size field.
+			binary.LittleEndian.PutUint32(p.writeBuf[writeBufIndex:], uint32(len(msg)))
+
+			// 4. Increase writeBufIndex.
+			writeBufIndex += len(buf) + p.overhead
+		}
+		nn, err := p.Conn.Write(p.writeBuf[:writeBufIndex])
+		if err != nil {
+			// We need to calculate the actual data size that was
+			// written. This means we need to remove header,
+			// encryption overheads, and any partially-written
+			// frame data.
+			numOfWrittenFrames := int(math.Floor(float64(nn) / float64(altsRecordDefaultLength)))
+			return partialBStart + numOfWrittenFrames*p.payloadLengthLimit, err
+		}
+	}
+	return n, nil
+}
+
+func min(a, b int) int {
+	if a < b {
+		return a
+	}
+	return b
+}

+ 63 - 0
vendor/google.golang.org/grpc/credentials/alts/internal/conn/utils.go

@@ -0,0 +1,63 @@
+/*
+ *
+ * Copyright 2018 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package conn
+
+import core "google.golang.org/grpc/credentials/alts/internal"
+
+// NewOutCounter returns an outgoing counter initialized to the starting sequence
+// number for the client/server side of a connection.
+func NewOutCounter(s core.Side, overflowLen int) (c Counter) {
+	c.overflowLen = overflowLen
+	if s == core.ServerSide {
+		// Server counters in ALTS record have the little-endian high bit
+		// set.
+		c.value[counterLen-1] = 0x80
+	}
+	return
+}
+
+// NewInCounter returns an incoming counter initialized to the starting sequence
+// number for the client/server side of a connection. This is used in ALTS record
+// to check that incoming counters are as expected, since ALTS record guarantees
+// that messages are unwrapped in the same order that the peer wrapped them.
+func NewInCounter(s core.Side, overflowLen int) (c Counter) {
+	c.overflowLen = overflowLen
+	if s == core.ClientSide {
+		// Server counters in ALTS record have the little-endian high bit
+		// set.
+		c.value[counterLen-1] = 0x80
+	}
+	return
+}
+
+// CounterFromValue creates a new counter given an initial value.
+func CounterFromValue(value []byte, overflowLen int) (c Counter) {
+	c.overflowLen = overflowLen
+	copy(c.value[:], value)
+	return
+}
+
+// CounterSide returns the connection side (client/server) a sequence counter is
+// associated with.
+func CounterSide(c []byte) core.Side {
+	if c[counterLen-1]&0x80 == 0x80 {
+		return core.ServerSide
+	}
+	return core.ClientSide
+}

+ 375 - 0
vendor/google.golang.org/grpc/credentials/alts/internal/handshaker/handshaker.go

@@ -0,0 +1,375 @@
+/*
+ *
+ * Copyright 2018 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Package handshaker provides ALTS handshaking functionality for GCP.
+package handshaker
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"io"
+	"net"
+	"sync"
+
+	grpc "google.golang.org/grpc"
+	"google.golang.org/grpc/codes"
+	"google.golang.org/grpc/credentials"
+	core "google.golang.org/grpc/credentials/alts/internal"
+	"google.golang.org/grpc/credentials/alts/internal/authinfo"
+	"google.golang.org/grpc/credentials/alts/internal/conn"
+	altsgrpc "google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp"
+	altspb "google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp"
+)
+
+const (
+	// The maximum byte size of receive frames.
+	frameLimit              = 64 * 1024 // 64 KB
+	rekeyRecordProtocolName = "ALTSRP_GCM_AES128_REKEY"
+	// maxPendingHandshakes represents the maximum number of concurrent
+	// handshakes.
+	maxPendingHandshakes = 100
+)
+
+var (
+	hsProtocol      = altspb.HandshakeProtocol_ALTS
+	appProtocols    = []string{"grpc"}
+	recordProtocols = []string{rekeyRecordProtocolName}
+	keyLength       = map[string]int{
+		rekeyRecordProtocolName: 44,
+	}
+	altsRecordFuncs = map[string]conn.ALTSRecordFunc{
+		// ALTS handshaker protocols.
+		rekeyRecordProtocolName: func(s core.Side, keyData []byte) (conn.ALTSRecordCrypto, error) {
+			return conn.NewAES128GCMRekey(s, keyData)
+		},
+	}
+	// control number of concurrent created (but not closed) handshakers.
+	mu                   sync.Mutex
+	concurrentHandshakes = int64(0)
+	// errDropped occurs when maxPendingHandshakes is reached.
+	errDropped = errors.New("maximum number of concurrent ALTS handshakes is reached")
+	// errOutOfBound occurs when the handshake service returns a consumed
+	// bytes value larger than the buffer that was passed to it originally.
+	errOutOfBound = errors.New("handshaker service consumed bytes value is out-of-bound")
+)
+
+func init() {
+	for protocol, f := range altsRecordFuncs {
+		if err := conn.RegisterProtocol(protocol, f); err != nil {
+			panic(err)
+		}
+	}
+}
+
+func acquire() bool {
+	mu.Lock()
+	// If we need n to be configurable, we can pass it as an argument.
+	n := int64(1)
+	success := maxPendingHandshakes-concurrentHandshakes >= n
+	if success {
+		concurrentHandshakes += n
+	}
+	mu.Unlock()
+	return success
+}
+
+func release() {
+	mu.Lock()
+	// If we need n to be configurable, we can pass it as an argument.
+	n := int64(1)
+	concurrentHandshakes -= n
+	if concurrentHandshakes < 0 {
+		mu.Unlock()
+		panic("bad release")
+	}
+	mu.Unlock()
+}
+
+// ClientHandshakerOptions contains the client handshaker options that can
+// provided by the caller.
+type ClientHandshakerOptions struct {
+	// ClientIdentity is the handshaker client local identity.
+	ClientIdentity *altspb.Identity
+	// TargetName is the server service account name for secure name
+	// checking.
+	TargetName string
+	// TargetServiceAccounts contains a list of expected target service
+	// accounts. One of these accounts should match one of the accounts in
+	// the handshaker results. Otherwise, the handshake fails.
+	TargetServiceAccounts []string
+	// RPCVersions specifies the gRPC versions accepted by the client.
+	RPCVersions *altspb.RpcProtocolVersions
+}
+
+// ServerHandshakerOptions contains the server handshaker options that can
+// provided by the caller.
+type ServerHandshakerOptions struct {
+	// RPCVersions specifies the gRPC versions accepted by the server.
+	RPCVersions *altspb.RpcProtocolVersions
+}
+
+// DefaultClientHandshakerOptions returns the default client handshaker options.
+func DefaultClientHandshakerOptions() *ClientHandshakerOptions {
+	return &ClientHandshakerOptions{}
+}
+
+// DefaultServerHandshakerOptions returns the default client handshaker options.
+func DefaultServerHandshakerOptions() *ServerHandshakerOptions {
+	return &ServerHandshakerOptions{}
+}
+
+// TODO: add support for future local and remote endpoint in both client options
+//       and server options (server options struct does not exist now. When
+//       caller can provide endpoints, it should be created.
+
+// altsHandshaker is used to complete a ALTS handshaking between client and
+// server. This handshaker talks to the ALTS handshaker service in the metadata
+// server.
+type altsHandshaker struct {
+	// RPC stream used to access the ALTS Handshaker service.
+	stream altsgrpc.HandshakerService_DoHandshakeClient
+	// the connection to the peer.
+	conn net.Conn
+	// client handshake options.
+	clientOpts *ClientHandshakerOptions
+	// server handshake options.
+	serverOpts *ServerHandshakerOptions
+	// defines the side doing the handshake, client or server.
+	side core.Side
+}
+
+// NewClientHandshaker creates a ALTS handshaker for GCP which contains an RPC
+// stub created using the passed conn and used to talk to the ALTS Handshaker
+// service in the metadata server.
+func NewClientHandshaker(ctx context.Context, conn *grpc.ClientConn, c net.Conn, opts *ClientHandshakerOptions) (core.Handshaker, error) {
+	stream, err := altsgrpc.NewHandshakerServiceClient(conn).DoHandshake(ctx, grpc.WaitForReady(true))
+	if err != nil {
+		return nil, err
+	}
+	return &altsHandshaker{
+		stream:     stream,
+		conn:       c,
+		clientOpts: opts,
+		side:       core.ClientSide,
+	}, nil
+}
+
+// NewServerHandshaker creates a ALTS handshaker for GCP which contains an RPC
+// stub created using the passed conn and used to talk to the ALTS Handshaker
+// service in the metadata server.
+func NewServerHandshaker(ctx context.Context, conn *grpc.ClientConn, c net.Conn, opts *ServerHandshakerOptions) (core.Handshaker, error) {
+	stream, err := altsgrpc.NewHandshakerServiceClient(conn).DoHandshake(ctx, grpc.WaitForReady(true))
+	if err != nil {
+		return nil, err
+	}
+	return &altsHandshaker{
+		stream:     stream,
+		conn:       c,
+		serverOpts: opts,
+		side:       core.ServerSide,
+	}, nil
+}
+
+// ClientHandshake starts and completes a client ALTS handshaking for GCP. Once
+// done, ClientHandshake returns a secure connection.
+func (h *altsHandshaker) ClientHandshake(ctx context.Context) (net.Conn, credentials.AuthInfo, error) {
+	if !acquire() {
+		return nil, nil, errDropped
+	}
+	defer release()
+
+	if h.side != core.ClientSide {
+		return nil, nil, errors.New("only handshakers created using NewClientHandshaker can perform a client handshaker")
+	}
+
+	// Create target identities from service account list.
+	targetIdentities := make([]*altspb.Identity, 0, len(h.clientOpts.TargetServiceAccounts))
+	for _, account := range h.clientOpts.TargetServiceAccounts {
+		targetIdentities = append(targetIdentities, &altspb.Identity{
+			IdentityOneof: &altspb.Identity_ServiceAccount{
+				ServiceAccount: account,
+			},
+		})
+	}
+	req := &altspb.HandshakerReq{
+		ReqOneof: &altspb.HandshakerReq_ClientStart{
+			ClientStart: &altspb.StartClientHandshakeReq{
+				HandshakeSecurityProtocol: hsProtocol,
+				ApplicationProtocols:      appProtocols,
+				RecordProtocols:           recordProtocols,
+				TargetIdentities:          targetIdentities,
+				LocalIdentity:             h.clientOpts.ClientIdentity,
+				TargetName:                h.clientOpts.TargetName,
+				RpcVersions:               h.clientOpts.RPCVersions,
+			},
+		},
+	}
+
+	conn, result, err := h.doHandshake(req)
+	if err != nil {
+		return nil, nil, err
+	}
+	authInfo := authinfo.New(result)
+	return conn, authInfo, nil
+}
+
+// ServerHandshake starts and completes a server ALTS handshaking for GCP. Once
+// done, ServerHandshake returns a secure connection.
+func (h *altsHandshaker) ServerHandshake(ctx context.Context) (net.Conn, credentials.AuthInfo, error) {
+	if !acquire() {
+		return nil, nil, errDropped
+	}
+	defer release()
+
+	if h.side != core.ServerSide {
+		return nil, nil, errors.New("only handshakers created using NewServerHandshaker can perform a server handshaker")
+	}
+
+	p := make([]byte, frameLimit)
+	n, err := h.conn.Read(p)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// Prepare server parameters.
+	// TODO: currently only ALTS parameters are provided. Might need to use
+	//       more options in the future.
+	params := make(map[int32]*altspb.ServerHandshakeParameters)
+	params[int32(altspb.HandshakeProtocol_ALTS)] = &altspb.ServerHandshakeParameters{
+		RecordProtocols: recordProtocols,
+	}
+	req := &altspb.HandshakerReq{
+		ReqOneof: &altspb.HandshakerReq_ServerStart{
+			ServerStart: &altspb.StartServerHandshakeReq{
+				ApplicationProtocols: appProtocols,
+				HandshakeParameters:  params,
+				InBytes:              p[:n],
+				RpcVersions:          h.serverOpts.RPCVersions,
+			},
+		},
+	}
+
+	conn, result, err := h.doHandshake(req)
+	if err != nil {
+		return nil, nil, err
+	}
+	authInfo := authinfo.New(result)
+	return conn, authInfo, nil
+}
+
+func (h *altsHandshaker) doHandshake(req *altspb.HandshakerReq) (net.Conn, *altspb.HandshakerResult, error) {
+	resp, err := h.accessHandshakerService(req)
+	if err != nil {
+		return nil, nil, err
+	}
+	// Check of the returned status is an error.
+	if resp.GetStatus() != nil {
+		if got, want := resp.GetStatus().Code, uint32(codes.OK); got != want {
+			return nil, nil, fmt.Errorf("%v", resp.GetStatus().Details)
+		}
+	}
+
+	var extra []byte
+	if req.GetServerStart() != nil {
+		if resp.GetBytesConsumed() > uint32(len(req.GetServerStart().GetInBytes())) {
+			return nil, nil, errOutOfBound
+		}
+		extra = req.GetServerStart().GetInBytes()[resp.GetBytesConsumed():]
+	}
+	result, extra, err := h.processUntilDone(resp, extra)
+	if err != nil {
+		return nil, nil, err
+	}
+	// The handshaker returns a 128 bytes key. It should be truncated based
+	// on the returned record protocol.
+	keyLen, ok := keyLength[result.RecordProtocol]
+	if !ok {
+		return nil, nil, fmt.Errorf("unknown resulted record protocol %v", result.RecordProtocol)
+	}
+	sc, err := conn.NewConn(h.conn, h.side, result.GetRecordProtocol(), result.KeyData[:keyLen], extra)
+	if err != nil {
+		return nil, nil, err
+	}
+	return sc, result, nil
+}
+
+func (h *altsHandshaker) accessHandshakerService(req *altspb.HandshakerReq) (*altspb.HandshakerResp, error) {
+	if err := h.stream.Send(req); err != nil {
+		return nil, err
+	}
+	resp, err := h.stream.Recv()
+	if err != nil {
+		return nil, err
+	}
+	return resp, nil
+}
+
+// processUntilDone processes the handshake until the handshaker service returns
+// the results. Handshaker service takes care of frame parsing, so we read
+// whatever received from the network and send it to the handshaker service.
+func (h *altsHandshaker) processUntilDone(resp *altspb.HandshakerResp, extra []byte) (*altspb.HandshakerResult, []byte, error) {
+	for {
+		if len(resp.OutFrames) > 0 {
+			if _, err := h.conn.Write(resp.OutFrames); err != nil {
+				return nil, nil, err
+			}
+		}
+		if resp.Result != nil {
+			return resp.Result, extra, nil
+		}
+		buf := make([]byte, frameLimit)
+		n, err := h.conn.Read(buf)
+		if err != nil && err != io.EOF {
+			return nil, nil, err
+		}
+		// If there is nothing to send to the handshaker service, and
+		// nothing is received from the peer, then we are stuck.
+		// This covers the case when the peer is not responding. Note
+		// that handshaker service connection issues are caught in
+		// accessHandshakerService before we even get here.
+		if len(resp.OutFrames) == 0 && n == 0 {
+			return nil, nil, core.PeerNotRespondingError
+		}
+		// Append extra bytes from the previous interaction with the
+		// handshaker service with the current buffer read from conn.
+		p := append(extra, buf[:n]...)
+		// From here on, p and extra point to the same slice.
+		resp, err = h.accessHandshakerService(&altspb.HandshakerReq{
+			ReqOneof: &altspb.HandshakerReq_Next{
+				Next: &altspb.NextHandshakeMessageReq{
+					InBytes: p,
+				},
+			},
+		})
+		if err != nil {
+			return nil, nil, err
+		}
+		// Set extra based on handshaker service response.
+		if resp.GetBytesConsumed() > uint32(len(p)) {
+			return nil, nil, errOutOfBound
+		}
+		extra = p[resp.GetBytesConsumed():]
+	}
+}
+
+// Close terminates the Handshaker. It should be called when the caller obtains
+// the secure connection.
+func (h *altsHandshaker) Close() {
+	h.stream.CloseSend()
+}

+ 54 - 0
vendor/google.golang.org/grpc/credentials/alts/internal/handshaker/service/service.go

@@ -0,0 +1,54 @@
+/*
+ *
+ * Copyright 2018 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Package service manages connections between the VM application and the ALTS
+// handshaker service.
+package service
+
+import (
+	"sync"
+
+	grpc "google.golang.org/grpc"
+)
+
+var (
+	// hsConn represents a connection to hypervisor handshaker service.
+	hsConn *grpc.ClientConn
+	mu     sync.Mutex
+	// hsDialer will be reassigned in tests.
+	hsDialer = grpc.Dial
+)
+
+// Dial dials the handshake service in the hypervisor. If a connection has
+// already been established, this function returns it. Otherwise, a new
+// connection is created.
+func Dial(hsAddress string) (*grpc.ClientConn, error) {
+	mu.Lock()
+	defer mu.Unlock()
+
+	if hsConn == nil {
+		// Create a new connection to the handshaker service. Note that
+		// this connection stays open until the application is closed.
+		var err error
+		hsConn, err = hsDialer(hsAddress, grpc.WithInsecure())
+		if err != nil {
+			return nil, err
+		}
+	}
+	return hsConn, nil
+}

+ 152 - 0
vendor/google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp/altscontext.pb.go

@@ -0,0 +1,152 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: grpc/gcp/altscontext.proto
+
+package grpc_gcp
+
+import (
+	fmt "fmt"
+	proto "github.com/golang/protobuf/proto"
+	math "math"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
+
+type AltsContext struct {
+	// The application protocol negotiated for this connection.
+	ApplicationProtocol string `protobuf:"bytes,1,opt,name=application_protocol,json=applicationProtocol,proto3" json:"application_protocol,omitempty"`
+	// The record protocol negotiated for this connection.
+	RecordProtocol string `protobuf:"bytes,2,opt,name=record_protocol,json=recordProtocol,proto3" json:"record_protocol,omitempty"`
+	// The security level of the created secure channel.
+	SecurityLevel SecurityLevel `protobuf:"varint,3,opt,name=security_level,json=securityLevel,proto3,enum=grpc.gcp.SecurityLevel" json:"security_level,omitempty"`
+	// The peer service account.
+	PeerServiceAccount string `protobuf:"bytes,4,opt,name=peer_service_account,json=peerServiceAccount,proto3" json:"peer_service_account,omitempty"`
+	// The local service account.
+	LocalServiceAccount string `protobuf:"bytes,5,opt,name=local_service_account,json=localServiceAccount,proto3" json:"local_service_account,omitempty"`
+	// The RPC protocol versions supported by the peer.
+	PeerRpcVersions *RpcProtocolVersions `protobuf:"bytes,6,opt,name=peer_rpc_versions,json=peerRpcVersions,proto3" json:"peer_rpc_versions,omitempty"`
+	// Additional attributes of the peer.
+	PeerAttributes       map[string]string `protobuf:"bytes,7,rep,name=peer_attributes,json=peerAttributes,proto3" json:"peer_attributes,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+	XXX_NoUnkeyedLiteral struct{}          `json:"-"`
+	XXX_unrecognized     []byte            `json:"-"`
+	XXX_sizecache        int32             `json:"-"`
+}
+
+func (m *AltsContext) Reset()         { *m = AltsContext{} }
+func (m *AltsContext) String() string { return proto.CompactTextString(m) }
+func (*AltsContext) ProtoMessage()    {}
+func (*AltsContext) Descriptor() ([]byte, []int) {
+	return fileDescriptor_6647a41e53a575a3, []int{0}
+}
+
+func (m *AltsContext) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_AltsContext.Unmarshal(m, b)
+}
+func (m *AltsContext) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_AltsContext.Marshal(b, m, deterministic)
+}
+func (m *AltsContext) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_AltsContext.Merge(m, src)
+}
+func (m *AltsContext) XXX_Size() int {
+	return xxx_messageInfo_AltsContext.Size(m)
+}
+func (m *AltsContext) XXX_DiscardUnknown() {
+	xxx_messageInfo_AltsContext.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_AltsContext proto.InternalMessageInfo
+
+func (m *AltsContext) GetApplicationProtocol() string {
+	if m != nil {
+		return m.ApplicationProtocol
+	}
+	return ""
+}
+
+func (m *AltsContext) GetRecordProtocol() string {
+	if m != nil {
+		return m.RecordProtocol
+	}
+	return ""
+}
+
+func (m *AltsContext) GetSecurityLevel() SecurityLevel {
+	if m != nil {
+		return m.SecurityLevel
+	}
+	return SecurityLevel_SECURITY_NONE
+}
+
+func (m *AltsContext) GetPeerServiceAccount() string {
+	if m != nil {
+		return m.PeerServiceAccount
+	}
+	return ""
+}
+
+func (m *AltsContext) GetLocalServiceAccount() string {
+	if m != nil {
+		return m.LocalServiceAccount
+	}
+	return ""
+}
+
+func (m *AltsContext) GetPeerRpcVersions() *RpcProtocolVersions {
+	if m != nil {
+		return m.PeerRpcVersions
+	}
+	return nil
+}
+
+func (m *AltsContext) GetPeerAttributes() map[string]string {
+	if m != nil {
+		return m.PeerAttributes
+	}
+	return nil
+}
+
+func init() {
+	proto.RegisterType((*AltsContext)(nil), "grpc.gcp.AltsContext")
+	proto.RegisterMapType((map[string]string)(nil), "grpc.gcp.AltsContext.PeerAttributesEntry")
+}
+
+func init() { proto.RegisterFile("grpc/gcp/altscontext.proto", fileDescriptor_6647a41e53a575a3) }
+
+var fileDescriptor_6647a41e53a575a3 = []byte{
+	// 411 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x92, 0x4d, 0x6f, 0x13, 0x31,
+	0x10, 0x86, 0xb5, 0x0d, 0x2d, 0xe0, 0x88, 0xb4, 0xb8, 0xa9, 0x58, 0x45, 0x42, 0x8a, 0xb8, 0xb0,
+	0x5c, 0x76, 0x21, 0x5c, 0x10, 0x07, 0x50, 0x8a, 0x38, 0x20, 0x71, 0x88, 0xb6, 0x12, 0x07, 0x2e,
+	0x2b, 0x77, 0x3a, 0xb2, 0x2c, 0x5c, 0x8f, 0x35, 0x76, 0x22, 0xf2, 0xb3, 0xf9, 0x07, 0x68, 0xed,
+	0xcd, 0x07, 0x1f, 0xb7, 0x9d, 0x79, 0x9f, 0x19, 0xbf, 0xb3, 0x33, 0x62, 0xa6, 0xd9, 0x43, 0xa3,
+	0xc1, 0x37, 0xca, 0xc6, 0x00, 0xe4, 0x22, 0xfe, 0x8c, 0xb5, 0x67, 0x8a, 0x24, 0x1f, 0xf5, 0x5a,
+	0xad, 0xc1, 0xcf, 0xaa, 0x3d, 0x15, 0x59, 0xb9, 0xe0, 0x89, 0x63, 0x17, 0x10, 0xd6, 0x6c, 0xe2,
+	0xb6, 0x03, 0xba, 0xbf, 0x27, 0x97, 0x6b, 0x5e, 0xfc, 0x1a, 0x89, 0xf1, 0xd2, 0xc6, 0xf0, 0x29,
+	0x77, 0x92, 0x6f, 0xc4, 0x54, 0x79, 0x6f, 0x0d, 0xa8, 0x68, 0xc8, 0x75, 0x09, 0x02, 0xb2, 0x65,
+	0x31, 0x2f, 0xaa, 0xc7, 0xed, 0xe5, 0x91, 0xb6, 0x1a, 0x24, 0xf9, 0x52, 0x9c, 0x33, 0x02, 0xf1,
+	0xdd, 0x81, 0x3e, 0x49, 0xf4, 0x24, 0xa7, 0xf7, 0xe0, 0x07, 0x31, 0xd9, 0x9b, 0xb0, 0xb8, 0x41,
+	0x5b, 0x8e, 0xe6, 0x45, 0x35, 0x59, 0x3c, 0xab, 0x77, 0xc6, 0xeb, 0x9b, 0x41, 0xff, 0xda, 0xcb,
+	0xed, 0x93, 0x70, 0x1c, 0xca, 0xd7, 0x62, 0xea, 0x11, 0xb9, 0x0b, 0xc8, 0x1b, 0x03, 0xd8, 0x29,
+	0x00, 0x5a, 0xbb, 0x58, 0x3e, 0x48, 0xaf, 0xc9, 0x5e, 0xbb, 0xc9, 0xd2, 0x32, 0x2b, 0x72, 0x21,
+	0xae, 0x2c, 0x81, 0xb2, 0xff, 0x94, 0x9c, 0xe6, 0x71, 0x92, 0xf8, 0x57, 0xcd, 0x17, 0xf1, 0x34,
+	0xbd, 0xc2, 0x1e, 0xba, 0x0d, 0x72, 0x30, 0xe4, 0x42, 0x79, 0x36, 0x2f, 0xaa, 0xf1, 0xe2, 0xf9,
+	0xc1, 0x68, 0xeb, 0x61, 0x37, 0xd7, 0xb7, 0x01, 0x6a, 0xcf, 0xfb, 0xba, 0xd6, 0xc3, 0x2e, 0x21,
+	0x5b, 0x91, 0x52, 0x9d, 0x8a, 0x91, 0xcd, 0xed, 0x3a, 0x62, 0x28, 0x1f, 0xce, 0x47, 0xd5, 0x78,
+	0xf1, 0xea, 0xd0, 0xe8, 0xe8, 0xe7, 0xd7, 0x2b, 0x44, 0x5e, 0xee, 0xd9, 0xcf, 0x2e, 0xf2, 0xb6,
+	0x9d, 0xf8, 0x3f, 0x92, 0xb3, 0xa5, 0xb8, 0xfc, 0x0f, 0x26, 0x2f, 0xc4, 0xe8, 0x07, 0x6e, 0x87,
+	0x35, 0xf5, 0x9f, 0x72, 0x2a, 0x4e, 0x37, 0xca, 0xae, 0x71, 0x58, 0x46, 0x0e, 0xde, 0x9f, 0xbc,
+	0x2b, 0xae, 0xad, 0xb8, 0x32, 0x94, 0x1d, 0xf4, 0x47, 0x54, 0x1b, 0x17, 0x91, 0x9d, 0xb2, 0xd7,
+	0x17, 0x47, 0x66, 0xd2, 0x74, 0xab, 0xe2, 0xfb, 0x47, 0x4d, 0xa4, 0x2d, 0xd6, 0x9a, 0xac, 0x72,
+	0xba, 0x26, 0xd6, 0x4d, 0x3a, 0x2e, 0x60, 0xbc, 0x43, 0x17, 0x8d, 0xb2, 0x21, 0x9d, 0x62, 0xb3,
+	0xeb, 0xd2, 0xa4, 0x2b, 0x48, 0x50, 0xa7, 0xc1, 0xdf, 0x9e, 0xa5, 0xf8, 0xed, 0xef, 0x00, 0x00,
+	0x00, 0xff, 0xff, 0x9b, 0x8c, 0xe4, 0x6a, 0xba, 0x02, 0x00, 0x00,
+}

+ 1105 - 0
vendor/google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp/handshaker.pb.go

@@ -0,0 +1,1105 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: grpc/gcp/handshaker.proto
+
+package grpc_gcp
+
+import (
+	context "context"
+	fmt "fmt"
+	proto "github.com/golang/protobuf/proto"
+	grpc "google.golang.org/grpc"
+	codes "google.golang.org/grpc/codes"
+	status "google.golang.org/grpc/status"
+	math "math"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
+
+type HandshakeProtocol int32
+
+const (
+	// Default value.
+	HandshakeProtocol_HANDSHAKE_PROTOCOL_UNSPECIFIED HandshakeProtocol = 0
+	// TLS handshake protocol.
+	HandshakeProtocol_TLS HandshakeProtocol = 1
+	// Application Layer Transport Security handshake protocol.
+	HandshakeProtocol_ALTS HandshakeProtocol = 2
+)
+
+var HandshakeProtocol_name = map[int32]string{
+	0: "HANDSHAKE_PROTOCOL_UNSPECIFIED",
+	1: "TLS",
+	2: "ALTS",
+}
+
+var HandshakeProtocol_value = map[string]int32{
+	"HANDSHAKE_PROTOCOL_UNSPECIFIED": 0,
+	"TLS":                            1,
+	"ALTS":                           2,
+}
+
+func (x HandshakeProtocol) String() string {
+	return proto.EnumName(HandshakeProtocol_name, int32(x))
+}
+
+func (HandshakeProtocol) EnumDescriptor() ([]byte, []int) {
+	return fileDescriptor_54c074f40c7c7e99, []int{0}
+}
+
+type NetworkProtocol int32
+
+const (
+	NetworkProtocol_NETWORK_PROTOCOL_UNSPECIFIED NetworkProtocol = 0
+	NetworkProtocol_TCP                          NetworkProtocol = 1
+	NetworkProtocol_UDP                          NetworkProtocol = 2
+)
+
+var NetworkProtocol_name = map[int32]string{
+	0: "NETWORK_PROTOCOL_UNSPECIFIED",
+	1: "TCP",
+	2: "UDP",
+}
+
+var NetworkProtocol_value = map[string]int32{
+	"NETWORK_PROTOCOL_UNSPECIFIED": 0,
+	"TCP":                          1,
+	"UDP":                          2,
+}
+
+func (x NetworkProtocol) String() string {
+	return proto.EnumName(NetworkProtocol_name, int32(x))
+}
+
+func (NetworkProtocol) EnumDescriptor() ([]byte, []int) {
+	return fileDescriptor_54c074f40c7c7e99, []int{1}
+}
+
+type Endpoint struct {
+	// IP address. It should contain an IPv4 or IPv6 string literal, e.g.
+	// "192.168.0.1" or "2001:db8::1".
+	IpAddress string `protobuf:"bytes,1,opt,name=ip_address,json=ipAddress,proto3" json:"ip_address,omitempty"`
+	// Port number.
+	Port int32 `protobuf:"varint,2,opt,name=port,proto3" json:"port,omitempty"`
+	// Network protocol (e.g., TCP, UDP) associated with this endpoint.
+	Protocol             NetworkProtocol `protobuf:"varint,3,opt,name=protocol,proto3,enum=grpc.gcp.NetworkProtocol" json:"protocol,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}        `json:"-"`
+	XXX_unrecognized     []byte          `json:"-"`
+	XXX_sizecache        int32           `json:"-"`
+}
+
+func (m *Endpoint) Reset()         { *m = Endpoint{} }
+func (m *Endpoint) String() string { return proto.CompactTextString(m) }
+func (*Endpoint) ProtoMessage()    {}
+func (*Endpoint) Descriptor() ([]byte, []int) {
+	return fileDescriptor_54c074f40c7c7e99, []int{0}
+}
+
+func (m *Endpoint) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Endpoint.Unmarshal(m, b)
+}
+func (m *Endpoint) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Endpoint.Marshal(b, m, deterministic)
+}
+func (m *Endpoint) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Endpoint.Merge(m, src)
+}
+func (m *Endpoint) XXX_Size() int {
+	return xxx_messageInfo_Endpoint.Size(m)
+}
+func (m *Endpoint) XXX_DiscardUnknown() {
+	xxx_messageInfo_Endpoint.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Endpoint proto.InternalMessageInfo
+
+func (m *Endpoint) GetIpAddress() string {
+	if m != nil {
+		return m.IpAddress
+	}
+	return ""
+}
+
+func (m *Endpoint) GetPort() int32 {
+	if m != nil {
+		return m.Port
+	}
+	return 0
+}
+
+func (m *Endpoint) GetProtocol() NetworkProtocol {
+	if m != nil {
+		return m.Protocol
+	}
+	return NetworkProtocol_NETWORK_PROTOCOL_UNSPECIFIED
+}
+
+type Identity struct {
+	// Types that are valid to be assigned to IdentityOneof:
+	//	*Identity_ServiceAccount
+	//	*Identity_Hostname
+	IdentityOneof isIdentity_IdentityOneof `protobuf_oneof:"identity_oneof"`
+	// Additional attributes of the identity.
+	Attributes           map[string]string `protobuf:"bytes,3,rep,name=attributes,proto3" json:"attributes,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+	XXX_NoUnkeyedLiteral struct{}          `json:"-"`
+	XXX_unrecognized     []byte            `json:"-"`
+	XXX_sizecache        int32             `json:"-"`
+}
+
+func (m *Identity) Reset()         { *m = Identity{} }
+func (m *Identity) String() string { return proto.CompactTextString(m) }
+func (*Identity) ProtoMessage()    {}
+func (*Identity) Descriptor() ([]byte, []int) {
+	return fileDescriptor_54c074f40c7c7e99, []int{1}
+}
+
+func (m *Identity) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Identity.Unmarshal(m, b)
+}
+func (m *Identity) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Identity.Marshal(b, m, deterministic)
+}
+func (m *Identity) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Identity.Merge(m, src)
+}
+func (m *Identity) XXX_Size() int {
+	return xxx_messageInfo_Identity.Size(m)
+}
+func (m *Identity) XXX_DiscardUnknown() {
+	xxx_messageInfo_Identity.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Identity proto.InternalMessageInfo
+
+type isIdentity_IdentityOneof interface {
+	isIdentity_IdentityOneof()
+}
+
+type Identity_ServiceAccount struct {
+	ServiceAccount string `protobuf:"bytes,1,opt,name=service_account,json=serviceAccount,proto3,oneof"`
+}
+
+type Identity_Hostname struct {
+	Hostname string `protobuf:"bytes,2,opt,name=hostname,proto3,oneof"`
+}
+
+func (*Identity_ServiceAccount) isIdentity_IdentityOneof() {}
+
+func (*Identity_Hostname) isIdentity_IdentityOneof() {}
+
+func (m *Identity) GetIdentityOneof() isIdentity_IdentityOneof {
+	if m != nil {
+		return m.IdentityOneof
+	}
+	return nil
+}
+
+func (m *Identity) GetServiceAccount() string {
+	if x, ok := m.GetIdentityOneof().(*Identity_ServiceAccount); ok {
+		return x.ServiceAccount
+	}
+	return ""
+}
+
+func (m *Identity) GetHostname() string {
+	if x, ok := m.GetIdentityOneof().(*Identity_Hostname); ok {
+		return x.Hostname
+	}
+	return ""
+}
+
+func (m *Identity) GetAttributes() map[string]string {
+	if m != nil {
+		return m.Attributes
+	}
+	return nil
+}
+
+// XXX_OneofWrappers is for the internal use of the proto package.
+func (*Identity) XXX_OneofWrappers() []interface{} {
+	return []interface{}{
+		(*Identity_ServiceAccount)(nil),
+		(*Identity_Hostname)(nil),
+	}
+}
+
+type StartClientHandshakeReq struct {
+	// Handshake security protocol requested by the client.
+	HandshakeSecurityProtocol HandshakeProtocol `protobuf:"varint,1,opt,name=handshake_security_protocol,json=handshakeSecurityProtocol,proto3,enum=grpc.gcp.HandshakeProtocol" json:"handshake_security_protocol,omitempty"`
+	// The application protocols supported by the client, e.g., "h2" (for http2),
+	// "grpc".
+	ApplicationProtocols []string `protobuf:"bytes,2,rep,name=application_protocols,json=applicationProtocols,proto3" json:"application_protocols,omitempty"`
+	// The record protocols supported by the client, e.g.,
+	// "ALTSRP_GCM_AES128".
+	RecordProtocols []string `protobuf:"bytes,3,rep,name=record_protocols,json=recordProtocols,proto3" json:"record_protocols,omitempty"`
+	// (Optional) Describes which server identities are acceptable by the client.
+	// If target identities are provided and none of them matches the peer
+	// identity of the server, handshake will fail.
+	TargetIdentities []*Identity `protobuf:"bytes,4,rep,name=target_identities,json=targetIdentities,proto3" json:"target_identities,omitempty"`
+	// (Optional) Application may specify a local identity. Otherwise, the
+	// handshaker chooses a default local identity.
+	LocalIdentity *Identity `protobuf:"bytes,5,opt,name=local_identity,json=localIdentity,proto3" json:"local_identity,omitempty"`
+	// (Optional) Local endpoint information of the connection to the server,
+	// such as local IP address, port number, and network protocol.
+	LocalEndpoint *Endpoint `protobuf:"bytes,6,opt,name=local_endpoint,json=localEndpoint,proto3" json:"local_endpoint,omitempty"`
+	// (Optional) Endpoint information of the remote server, such as IP address,
+	// port number, and network protocol.
+	RemoteEndpoint *Endpoint `protobuf:"bytes,7,opt,name=remote_endpoint,json=remoteEndpoint,proto3" json:"remote_endpoint,omitempty"`
+	// (Optional) If target name is provided, a secure naming check is performed
+	// to verify that the peer authenticated identity is indeed authorized to run
+	// the target name.
+	TargetName string `protobuf:"bytes,8,opt,name=target_name,json=targetName,proto3" json:"target_name,omitempty"`
+	// (Optional) RPC protocol versions supported by the client.
+	RpcVersions *RpcProtocolVersions `protobuf:"bytes,9,opt,name=rpc_versions,json=rpcVersions,proto3" json:"rpc_versions,omitempty"`
+	// (Optional) Maximum frame size supported by the client.
+	MaxFrameSize         uint32   `protobuf:"varint,10,opt,name=max_frame_size,json=maxFrameSize,proto3" json:"max_frame_size,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *StartClientHandshakeReq) Reset()         { *m = StartClientHandshakeReq{} }
+func (m *StartClientHandshakeReq) String() string { return proto.CompactTextString(m) }
+func (*StartClientHandshakeReq) ProtoMessage()    {}
+func (*StartClientHandshakeReq) Descriptor() ([]byte, []int) {
+	return fileDescriptor_54c074f40c7c7e99, []int{2}
+}
+
+func (m *StartClientHandshakeReq) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_StartClientHandshakeReq.Unmarshal(m, b)
+}
+func (m *StartClientHandshakeReq) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_StartClientHandshakeReq.Marshal(b, m, deterministic)
+}
+func (m *StartClientHandshakeReq) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_StartClientHandshakeReq.Merge(m, src)
+}
+func (m *StartClientHandshakeReq) XXX_Size() int {
+	return xxx_messageInfo_StartClientHandshakeReq.Size(m)
+}
+func (m *StartClientHandshakeReq) XXX_DiscardUnknown() {
+	xxx_messageInfo_StartClientHandshakeReq.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_StartClientHandshakeReq proto.InternalMessageInfo
+
+func (m *StartClientHandshakeReq) GetHandshakeSecurityProtocol() HandshakeProtocol {
+	if m != nil {
+		return m.HandshakeSecurityProtocol
+	}
+	return HandshakeProtocol_HANDSHAKE_PROTOCOL_UNSPECIFIED
+}
+
+func (m *StartClientHandshakeReq) GetApplicationProtocols() []string {
+	if m != nil {
+		return m.ApplicationProtocols
+	}
+	return nil
+}
+
+func (m *StartClientHandshakeReq) GetRecordProtocols() []string {
+	if m != nil {
+		return m.RecordProtocols
+	}
+	return nil
+}
+
+func (m *StartClientHandshakeReq) GetTargetIdentities() []*Identity {
+	if m != nil {
+		return m.TargetIdentities
+	}
+	return nil
+}
+
+func (m *StartClientHandshakeReq) GetLocalIdentity() *Identity {
+	if m != nil {
+		return m.LocalIdentity
+	}
+	return nil
+}
+
+func (m *StartClientHandshakeReq) GetLocalEndpoint() *Endpoint {
+	if m != nil {
+		return m.LocalEndpoint
+	}
+	return nil
+}
+
+func (m *StartClientHandshakeReq) GetRemoteEndpoint() *Endpoint {
+	if m != nil {
+		return m.RemoteEndpoint
+	}
+	return nil
+}
+
+func (m *StartClientHandshakeReq) GetTargetName() string {
+	if m != nil {
+		return m.TargetName
+	}
+	return ""
+}
+
+func (m *StartClientHandshakeReq) GetRpcVersions() *RpcProtocolVersions {
+	if m != nil {
+		return m.RpcVersions
+	}
+	return nil
+}
+
+func (m *StartClientHandshakeReq) GetMaxFrameSize() uint32 {
+	if m != nil {
+		return m.MaxFrameSize
+	}
+	return 0
+}
+
+type ServerHandshakeParameters struct {
+	// The record protocols supported by the server, e.g.,
+	// "ALTSRP_GCM_AES128".
+	RecordProtocols []string `protobuf:"bytes,1,rep,name=record_protocols,json=recordProtocols,proto3" json:"record_protocols,omitempty"`
+	// (Optional) A list of local identities supported by the server, if
+	// specified. Otherwise, the handshaker chooses a default local identity.
+	LocalIdentities      []*Identity `protobuf:"bytes,2,rep,name=local_identities,json=localIdentities,proto3" json:"local_identities,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}    `json:"-"`
+	XXX_unrecognized     []byte      `json:"-"`
+	XXX_sizecache        int32       `json:"-"`
+}
+
+func (m *ServerHandshakeParameters) Reset()         { *m = ServerHandshakeParameters{} }
+func (m *ServerHandshakeParameters) String() string { return proto.CompactTextString(m) }
+func (*ServerHandshakeParameters) ProtoMessage()    {}
+func (*ServerHandshakeParameters) Descriptor() ([]byte, []int) {
+	return fileDescriptor_54c074f40c7c7e99, []int{3}
+}
+
+func (m *ServerHandshakeParameters) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_ServerHandshakeParameters.Unmarshal(m, b)
+}
+func (m *ServerHandshakeParameters) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_ServerHandshakeParameters.Marshal(b, m, deterministic)
+}
+func (m *ServerHandshakeParameters) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_ServerHandshakeParameters.Merge(m, src)
+}
+func (m *ServerHandshakeParameters) XXX_Size() int {
+	return xxx_messageInfo_ServerHandshakeParameters.Size(m)
+}
+func (m *ServerHandshakeParameters) XXX_DiscardUnknown() {
+	xxx_messageInfo_ServerHandshakeParameters.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ServerHandshakeParameters proto.InternalMessageInfo
+
+func (m *ServerHandshakeParameters) GetRecordProtocols() []string {
+	if m != nil {
+		return m.RecordProtocols
+	}
+	return nil
+}
+
+func (m *ServerHandshakeParameters) GetLocalIdentities() []*Identity {
+	if m != nil {
+		return m.LocalIdentities
+	}
+	return nil
+}
+
+type StartServerHandshakeReq struct {
+	// The application protocols supported by the server, e.g., "h2" (for http2),
+	// "grpc".
+	ApplicationProtocols []string `protobuf:"bytes,1,rep,name=application_protocols,json=applicationProtocols,proto3" json:"application_protocols,omitempty"`
+	// Handshake parameters (record protocols and local identities supported by
+	// the server) mapped by the handshake protocol. Each handshake security
+	// protocol (e.g., TLS or ALTS) has its own set of record protocols and local
+	// identities. Since protobuf does not support enum as key to the map, the key
+	// to handshake_parameters is the integer value of HandshakeProtocol enum.
+	HandshakeParameters map[int32]*ServerHandshakeParameters `protobuf:"bytes,2,rep,name=handshake_parameters,json=handshakeParameters,proto3" json:"handshake_parameters,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+	// Bytes in out_frames returned from the peer's HandshakerResp. It is possible
+	// that the peer's out_frames are split into multiple HandshakReq messages.
+	InBytes []byte `protobuf:"bytes,3,opt,name=in_bytes,json=inBytes,proto3" json:"in_bytes,omitempty"`
+	// (Optional) Local endpoint information of the connection to the client,
+	// such as local IP address, port number, and network protocol.
+	LocalEndpoint *Endpoint `protobuf:"bytes,4,opt,name=local_endpoint,json=localEndpoint,proto3" json:"local_endpoint,omitempty"`
+	// (Optional) Endpoint information of the remote client, such as IP address,
+	// port number, and network protocol.
+	RemoteEndpoint *Endpoint `protobuf:"bytes,5,opt,name=remote_endpoint,json=remoteEndpoint,proto3" json:"remote_endpoint,omitempty"`
+	// (Optional) RPC protocol versions supported by the server.
+	RpcVersions *RpcProtocolVersions `protobuf:"bytes,6,opt,name=rpc_versions,json=rpcVersions,proto3" json:"rpc_versions,omitempty"`
+	// (Optional) Maximum frame size supported by the server.
+	MaxFrameSize         uint32   `protobuf:"varint,7,opt,name=max_frame_size,json=maxFrameSize,proto3" json:"max_frame_size,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *StartServerHandshakeReq) Reset()         { *m = StartServerHandshakeReq{} }
+func (m *StartServerHandshakeReq) String() string { return proto.CompactTextString(m) }
+func (*StartServerHandshakeReq) ProtoMessage()    {}
+func (*StartServerHandshakeReq) Descriptor() ([]byte, []int) {
+	return fileDescriptor_54c074f40c7c7e99, []int{4}
+}
+
+func (m *StartServerHandshakeReq) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_StartServerHandshakeReq.Unmarshal(m, b)
+}
+func (m *StartServerHandshakeReq) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_StartServerHandshakeReq.Marshal(b, m, deterministic)
+}
+func (m *StartServerHandshakeReq) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_StartServerHandshakeReq.Merge(m, src)
+}
+func (m *StartServerHandshakeReq) XXX_Size() int {
+	return xxx_messageInfo_StartServerHandshakeReq.Size(m)
+}
+func (m *StartServerHandshakeReq) XXX_DiscardUnknown() {
+	xxx_messageInfo_StartServerHandshakeReq.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_StartServerHandshakeReq proto.InternalMessageInfo
+
+func (m *StartServerHandshakeReq) GetApplicationProtocols() []string {
+	if m != nil {
+		return m.ApplicationProtocols
+	}
+	return nil
+}
+
+func (m *StartServerHandshakeReq) GetHandshakeParameters() map[int32]*ServerHandshakeParameters {
+	if m != nil {
+		return m.HandshakeParameters
+	}
+	return nil
+}
+
+func (m *StartServerHandshakeReq) GetInBytes() []byte {
+	if m != nil {
+		return m.InBytes
+	}
+	return nil
+}
+
+func (m *StartServerHandshakeReq) GetLocalEndpoint() *Endpoint {
+	if m != nil {
+		return m.LocalEndpoint
+	}
+	return nil
+}
+
+func (m *StartServerHandshakeReq) GetRemoteEndpoint() *Endpoint {
+	if m != nil {
+		return m.RemoteEndpoint
+	}
+	return nil
+}
+
+func (m *StartServerHandshakeReq) GetRpcVersions() *RpcProtocolVersions {
+	if m != nil {
+		return m.RpcVersions
+	}
+	return nil
+}
+
+func (m *StartServerHandshakeReq) GetMaxFrameSize() uint32 {
+	if m != nil {
+		return m.MaxFrameSize
+	}
+	return 0
+}
+
+type NextHandshakeMessageReq struct {
+	// Bytes in out_frames returned from the peer's HandshakerResp. It is possible
+	// that the peer's out_frames are split into multiple NextHandshakerMessageReq
+	// messages.
+	InBytes              []byte   `protobuf:"bytes,1,opt,name=in_bytes,json=inBytes,proto3" json:"in_bytes,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *NextHandshakeMessageReq) Reset()         { *m = NextHandshakeMessageReq{} }
+func (m *NextHandshakeMessageReq) String() string { return proto.CompactTextString(m) }
+func (*NextHandshakeMessageReq) ProtoMessage()    {}
+func (*NextHandshakeMessageReq) Descriptor() ([]byte, []int) {
+	return fileDescriptor_54c074f40c7c7e99, []int{5}
+}
+
+func (m *NextHandshakeMessageReq) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_NextHandshakeMessageReq.Unmarshal(m, b)
+}
+func (m *NextHandshakeMessageReq) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_NextHandshakeMessageReq.Marshal(b, m, deterministic)
+}
+func (m *NextHandshakeMessageReq) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_NextHandshakeMessageReq.Merge(m, src)
+}
+func (m *NextHandshakeMessageReq) XXX_Size() int {
+	return xxx_messageInfo_NextHandshakeMessageReq.Size(m)
+}
+func (m *NextHandshakeMessageReq) XXX_DiscardUnknown() {
+	xxx_messageInfo_NextHandshakeMessageReq.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_NextHandshakeMessageReq proto.InternalMessageInfo
+
+func (m *NextHandshakeMessageReq) GetInBytes() []byte {
+	if m != nil {
+		return m.InBytes
+	}
+	return nil
+}
+
+type HandshakerReq struct {
+	// Types that are valid to be assigned to ReqOneof:
+	//	*HandshakerReq_ClientStart
+	//	*HandshakerReq_ServerStart
+	//	*HandshakerReq_Next
+	ReqOneof             isHandshakerReq_ReqOneof `protobuf_oneof:"req_oneof"`
+	XXX_NoUnkeyedLiteral struct{}                 `json:"-"`
+	XXX_unrecognized     []byte                   `json:"-"`
+	XXX_sizecache        int32                    `json:"-"`
+}
+
+func (m *HandshakerReq) Reset()         { *m = HandshakerReq{} }
+func (m *HandshakerReq) String() string { return proto.CompactTextString(m) }
+func (*HandshakerReq) ProtoMessage()    {}
+func (*HandshakerReq) Descriptor() ([]byte, []int) {
+	return fileDescriptor_54c074f40c7c7e99, []int{6}
+}
+
+func (m *HandshakerReq) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_HandshakerReq.Unmarshal(m, b)
+}
+func (m *HandshakerReq) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_HandshakerReq.Marshal(b, m, deterministic)
+}
+func (m *HandshakerReq) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_HandshakerReq.Merge(m, src)
+}
+func (m *HandshakerReq) XXX_Size() int {
+	return xxx_messageInfo_HandshakerReq.Size(m)
+}
+func (m *HandshakerReq) XXX_DiscardUnknown() {
+	xxx_messageInfo_HandshakerReq.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_HandshakerReq proto.InternalMessageInfo
+
+type isHandshakerReq_ReqOneof interface {
+	isHandshakerReq_ReqOneof()
+}
+
+type HandshakerReq_ClientStart struct {
+	ClientStart *StartClientHandshakeReq `protobuf:"bytes,1,opt,name=client_start,json=clientStart,proto3,oneof"`
+}
+
+type HandshakerReq_ServerStart struct {
+	ServerStart *StartServerHandshakeReq `protobuf:"bytes,2,opt,name=server_start,json=serverStart,proto3,oneof"`
+}
+
+type HandshakerReq_Next struct {
+	Next *NextHandshakeMessageReq `protobuf:"bytes,3,opt,name=next,proto3,oneof"`
+}
+
+func (*HandshakerReq_ClientStart) isHandshakerReq_ReqOneof() {}
+
+func (*HandshakerReq_ServerStart) isHandshakerReq_ReqOneof() {}
+
+func (*HandshakerReq_Next) isHandshakerReq_ReqOneof() {}
+
+func (m *HandshakerReq) GetReqOneof() isHandshakerReq_ReqOneof {
+	if m != nil {
+		return m.ReqOneof
+	}
+	return nil
+}
+
+func (m *HandshakerReq) GetClientStart() *StartClientHandshakeReq {
+	if x, ok := m.GetReqOneof().(*HandshakerReq_ClientStart); ok {
+		return x.ClientStart
+	}
+	return nil
+}
+
+func (m *HandshakerReq) GetServerStart() *StartServerHandshakeReq {
+	if x, ok := m.GetReqOneof().(*HandshakerReq_ServerStart); ok {
+		return x.ServerStart
+	}
+	return nil
+}
+
+func (m *HandshakerReq) GetNext() *NextHandshakeMessageReq {
+	if x, ok := m.GetReqOneof().(*HandshakerReq_Next); ok {
+		return x.Next
+	}
+	return nil
+}
+
+// XXX_OneofWrappers is for the internal use of the proto package.
+func (*HandshakerReq) XXX_OneofWrappers() []interface{} {
+	return []interface{}{
+		(*HandshakerReq_ClientStart)(nil),
+		(*HandshakerReq_ServerStart)(nil),
+		(*HandshakerReq_Next)(nil),
+	}
+}
+
+type HandshakerResult struct {
+	// The application protocol negotiated for this connection.
+	ApplicationProtocol string `protobuf:"bytes,1,opt,name=application_protocol,json=applicationProtocol,proto3" json:"application_protocol,omitempty"`
+	// The record protocol negotiated for this connection.
+	RecordProtocol string `protobuf:"bytes,2,opt,name=record_protocol,json=recordProtocol,proto3" json:"record_protocol,omitempty"`
+	// Cryptographic key data. The key data may be more than the key length
+	// required for the record protocol, thus the client of the handshaker
+	// service needs to truncate the key data into the right key length.
+	KeyData []byte `protobuf:"bytes,3,opt,name=key_data,json=keyData,proto3" json:"key_data,omitempty"`
+	// The authenticated identity of the peer.
+	PeerIdentity *Identity `protobuf:"bytes,4,opt,name=peer_identity,json=peerIdentity,proto3" json:"peer_identity,omitempty"`
+	// The local identity used in the handshake.
+	LocalIdentity *Identity `protobuf:"bytes,5,opt,name=local_identity,json=localIdentity,proto3" json:"local_identity,omitempty"`
+	// Indicate whether the handshaker service client should keep the channel
+	// between the handshaker service open, e.g., in order to handle
+	// post-handshake messages in the future.
+	KeepChannelOpen bool `protobuf:"varint,6,opt,name=keep_channel_open,json=keepChannelOpen,proto3" json:"keep_channel_open,omitempty"`
+	// The RPC protocol versions supported by the peer.
+	PeerRpcVersions *RpcProtocolVersions `protobuf:"bytes,7,opt,name=peer_rpc_versions,json=peerRpcVersions,proto3" json:"peer_rpc_versions,omitempty"`
+	// The maximum frame size of the peer.
+	MaxFrameSize         uint32   `protobuf:"varint,8,opt,name=max_frame_size,json=maxFrameSize,proto3" json:"max_frame_size,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *HandshakerResult) Reset()         { *m = HandshakerResult{} }
+func (m *HandshakerResult) String() string { return proto.CompactTextString(m) }
+func (*HandshakerResult) ProtoMessage()    {}
+func (*HandshakerResult) Descriptor() ([]byte, []int) {
+	return fileDescriptor_54c074f40c7c7e99, []int{7}
+}
+
+func (m *HandshakerResult) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_HandshakerResult.Unmarshal(m, b)
+}
+func (m *HandshakerResult) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_HandshakerResult.Marshal(b, m, deterministic)
+}
+func (m *HandshakerResult) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_HandshakerResult.Merge(m, src)
+}
+func (m *HandshakerResult) XXX_Size() int {
+	return xxx_messageInfo_HandshakerResult.Size(m)
+}
+func (m *HandshakerResult) XXX_DiscardUnknown() {
+	xxx_messageInfo_HandshakerResult.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_HandshakerResult proto.InternalMessageInfo
+
+func (m *HandshakerResult) GetApplicationProtocol() string {
+	if m != nil {
+		return m.ApplicationProtocol
+	}
+	return ""
+}
+
+func (m *HandshakerResult) GetRecordProtocol() string {
+	if m != nil {
+		return m.RecordProtocol
+	}
+	return ""
+}
+
+func (m *HandshakerResult) GetKeyData() []byte {
+	if m != nil {
+		return m.KeyData
+	}
+	return nil
+}
+
+func (m *HandshakerResult) GetPeerIdentity() *Identity {
+	if m != nil {
+		return m.PeerIdentity
+	}
+	return nil
+}
+
+func (m *HandshakerResult) GetLocalIdentity() *Identity {
+	if m != nil {
+		return m.LocalIdentity
+	}
+	return nil
+}
+
+func (m *HandshakerResult) GetKeepChannelOpen() bool {
+	if m != nil {
+		return m.KeepChannelOpen
+	}
+	return false
+}
+
+func (m *HandshakerResult) GetPeerRpcVersions() *RpcProtocolVersions {
+	if m != nil {
+		return m.PeerRpcVersions
+	}
+	return nil
+}
+
+func (m *HandshakerResult) GetMaxFrameSize() uint32 {
+	if m != nil {
+		return m.MaxFrameSize
+	}
+	return 0
+}
+
+type HandshakerStatus struct {
+	// The status code. This could be the gRPC status code.
+	Code uint32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"`
+	// The status details.
+	Details              string   `protobuf:"bytes,2,opt,name=details,proto3" json:"details,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *HandshakerStatus) Reset()         { *m = HandshakerStatus{} }
+func (m *HandshakerStatus) String() string { return proto.CompactTextString(m) }
+func (*HandshakerStatus) ProtoMessage()    {}
+func (*HandshakerStatus) Descriptor() ([]byte, []int) {
+	return fileDescriptor_54c074f40c7c7e99, []int{8}
+}
+
+func (m *HandshakerStatus) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_HandshakerStatus.Unmarshal(m, b)
+}
+func (m *HandshakerStatus) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_HandshakerStatus.Marshal(b, m, deterministic)
+}
+func (m *HandshakerStatus) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_HandshakerStatus.Merge(m, src)
+}
+func (m *HandshakerStatus) XXX_Size() int {
+	return xxx_messageInfo_HandshakerStatus.Size(m)
+}
+func (m *HandshakerStatus) XXX_DiscardUnknown() {
+	xxx_messageInfo_HandshakerStatus.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_HandshakerStatus proto.InternalMessageInfo
+
+func (m *HandshakerStatus) GetCode() uint32 {
+	if m != nil {
+		return m.Code
+	}
+	return 0
+}
+
+func (m *HandshakerStatus) GetDetails() string {
+	if m != nil {
+		return m.Details
+	}
+	return ""
+}
+
+type HandshakerResp struct {
+	// Frames to be given to the peer for the NextHandshakeMessageReq. May be
+	// empty if no out_frames have to be sent to the peer or if in_bytes in the
+	// HandshakerReq are incomplete. All the non-empty out frames must be sent to
+	// the peer even if the handshaker status is not OK as these frames may
+	// contain the alert frames.
+	OutFrames []byte `protobuf:"bytes,1,opt,name=out_frames,json=outFrames,proto3" json:"out_frames,omitempty"`
+	// Number of bytes in the in_bytes consumed by the handshaker. It is possible
+	// that part of in_bytes in HandshakerReq was unrelated to the handshake
+	// process.
+	BytesConsumed uint32 `protobuf:"varint,2,opt,name=bytes_consumed,json=bytesConsumed,proto3" json:"bytes_consumed,omitempty"`
+	// This is set iff the handshake was successful. out_frames may still be set
+	// to frames that needs to be forwarded to the peer.
+	Result *HandshakerResult `protobuf:"bytes,3,opt,name=result,proto3" json:"result,omitempty"`
+	// Status of the handshaker.
+	Status               *HandshakerStatus `protobuf:"bytes,4,opt,name=status,proto3" json:"status,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}          `json:"-"`
+	XXX_unrecognized     []byte            `json:"-"`
+	XXX_sizecache        int32             `json:"-"`
+}
+
+func (m *HandshakerResp) Reset()         { *m = HandshakerResp{} }
+func (m *HandshakerResp) String() string { return proto.CompactTextString(m) }
+func (*HandshakerResp) ProtoMessage()    {}
+func (*HandshakerResp) Descriptor() ([]byte, []int) {
+	return fileDescriptor_54c074f40c7c7e99, []int{9}
+}
+
+func (m *HandshakerResp) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_HandshakerResp.Unmarshal(m, b)
+}
+func (m *HandshakerResp) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_HandshakerResp.Marshal(b, m, deterministic)
+}
+func (m *HandshakerResp) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_HandshakerResp.Merge(m, src)
+}
+func (m *HandshakerResp) XXX_Size() int {
+	return xxx_messageInfo_HandshakerResp.Size(m)
+}
+func (m *HandshakerResp) XXX_DiscardUnknown() {
+	xxx_messageInfo_HandshakerResp.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_HandshakerResp proto.InternalMessageInfo
+
+func (m *HandshakerResp) GetOutFrames() []byte {
+	if m != nil {
+		return m.OutFrames
+	}
+	return nil
+}
+
+func (m *HandshakerResp) GetBytesConsumed() uint32 {
+	if m != nil {
+		return m.BytesConsumed
+	}
+	return 0
+}
+
+func (m *HandshakerResp) GetResult() *HandshakerResult {
+	if m != nil {
+		return m.Result
+	}
+	return nil
+}
+
+func (m *HandshakerResp) GetStatus() *HandshakerStatus {
+	if m != nil {
+		return m.Status
+	}
+	return nil
+}
+
+func init() {
+	proto.RegisterEnum("grpc.gcp.HandshakeProtocol", HandshakeProtocol_name, HandshakeProtocol_value)
+	proto.RegisterEnum("grpc.gcp.NetworkProtocol", NetworkProtocol_name, NetworkProtocol_value)
+	proto.RegisterType((*Endpoint)(nil), "grpc.gcp.Endpoint")
+	proto.RegisterType((*Identity)(nil), "grpc.gcp.Identity")
+	proto.RegisterMapType((map[string]string)(nil), "grpc.gcp.Identity.AttributesEntry")
+	proto.RegisterType((*StartClientHandshakeReq)(nil), "grpc.gcp.StartClientHandshakeReq")
+	proto.RegisterType((*ServerHandshakeParameters)(nil), "grpc.gcp.ServerHandshakeParameters")
+	proto.RegisterType((*StartServerHandshakeReq)(nil), "grpc.gcp.StartServerHandshakeReq")
+	proto.RegisterMapType((map[int32]*ServerHandshakeParameters)(nil), "grpc.gcp.StartServerHandshakeReq.HandshakeParametersEntry")
+	proto.RegisterType((*NextHandshakeMessageReq)(nil), "grpc.gcp.NextHandshakeMessageReq")
+	proto.RegisterType((*HandshakerReq)(nil), "grpc.gcp.HandshakerReq")
+	proto.RegisterType((*HandshakerResult)(nil), "grpc.gcp.HandshakerResult")
+	proto.RegisterType((*HandshakerStatus)(nil), "grpc.gcp.HandshakerStatus")
+	proto.RegisterType((*HandshakerResp)(nil), "grpc.gcp.HandshakerResp")
+}
+
+func init() { proto.RegisterFile("grpc/gcp/handshaker.proto", fileDescriptor_54c074f40c7c7e99) }
+
+var fileDescriptor_54c074f40c7c7e99 = []byte{
+	// 1203 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0xdd, 0x6e, 0x1b, 0x45,
+	0x14, 0xce, 0xda, 0x4e, 0xe2, 0x1c, 0xc7, 0x3f, 0x99, 0xa6, 0xea, 0x26, 0x6d, 0xc1, 0x18, 0x10,
+	0x6e, 0x2f, 0x6c, 0x70, 0x41, 0xa5, 0x45, 0x55, 0x6b, 0x3b, 0x8e, 0x1c, 0x5a, 0x1c, 0x6b, 0x9d,
+	0x82, 0x44, 0x2f, 0x56, 0xd3, 0xf5, 0xd4, 0x59, 0x79, 0x3d, 0xb3, 0x9d, 0x19, 0x87, 0xb8, 0xf7,
+	0xbc, 0x04, 0xf7, 0xbc, 0x06, 0x2f, 0xc1, 0x33, 0x20, 0xf1, 0x18, 0x68, 0x67, 0x7f, 0x6d, 0xaf,
+	0xab, 0x22, 0xb8, 0xdb, 0x39, 0xf3, 0x7d, 0x67, 0xce, 0x9c, 0xf3, 0x9d, 0xb3, 0x03, 0x47, 0x13,
+	0xee, 0x5a, 0xcd, 0x89, 0xe5, 0x36, 0x2f, 0x31, 0x1d, 0x8b, 0x4b, 0x3c, 0x25, 0xbc, 0xe1, 0x72,
+	0x26, 0x19, 0xca, 0x7b, 0x5b, 0x8d, 0x89, 0xe5, 0x1e, 0xd7, 0x23, 0x90, 0xe4, 0x98, 0x0a, 0x97,
+	0x71, 0x69, 0x0a, 0x62, 0xcd, 0xb9, 0x2d, 0x17, 0xa6, 0xc5, 0x66, 0x33, 0x46, 0x7d, 0x4e, 0x4d,
+	0x42, 0xbe, 0x47, 0xc7, 0x2e, 0xb3, 0xa9, 0x44, 0x77, 0x01, 0x6c, 0xd7, 0xc4, 0xe3, 0x31, 0x27,
+	0x42, 0xe8, 0x5a, 0x55, 0xab, 0xef, 0x19, 0x7b, 0xb6, 0xdb, 0xf6, 0x0d, 0x08, 0x41, 0xce, 0x73,
+	0xa4, 0x67, 0xaa, 0x5a, 0x7d, 0xdb, 0x50, 0xdf, 0xe8, 0x1b, 0xc8, 0x2b, 0x3f, 0x16, 0x73, 0xf4,
+	0x6c, 0x55, 0xab, 0x97, 0x5a, 0x47, 0x8d, 0x30, 0x8a, 0xc6, 0x80, 0xc8, 0x5f, 0x18, 0x9f, 0x0e,
+	0x03, 0x80, 0x11, 0x41, 0x6b, 0x7f, 0x6b, 0x90, 0x3f, 0x1b, 0x13, 0x2a, 0x6d, 0xb9, 0x40, 0xf7,
+	0xa0, 0x2c, 0x08, 0xbf, 0xb2, 0x2d, 0x62, 0x62, 0xcb, 0x62, 0x73, 0x2a, 0xfd, 0xb3, 0xfb, 0x5b,
+	0x46, 0x29, 0xd8, 0x68, 0xfb, 0x76, 0x74, 0x07, 0xf2, 0x97, 0x4c, 0x48, 0x8a, 0x67, 0x44, 0x85,
+	0xe1, 0x61, 0x22, 0x0b, 0xea, 0x00, 0x60, 0x29, 0xb9, 0xfd, 0x7a, 0x2e, 0x89, 0xd0, 0xb3, 0xd5,
+	0x6c, 0xbd, 0xd0, 0xaa, 0xc5, 0xe1, 0x84, 0x07, 0x36, 0xda, 0x11, 0xa8, 0x47, 0x25, 0x5f, 0x18,
+	0x09, 0xd6, 0xf1, 0x13, 0x28, 0xaf, 0x6c, 0xa3, 0x0a, 0x64, 0xa7, 0x64, 0x11, 0xe4, 0xc3, 0xfb,
+	0x44, 0x87, 0xb0, 0x7d, 0x85, 0x9d, 0x79, 0x10, 0x83, 0xe1, 0x2f, 0x1e, 0x67, 0xbe, 0xd5, 0x3a,
+	0x15, 0x28, 0xd9, 0xc1, 0x31, 0x26, 0xa3, 0x84, 0xbd, 0xa9, 0xfd, 0x99, 0x83, 0x5b, 0x23, 0x89,
+	0xb9, 0xec, 0x3a, 0x36, 0xa1, 0xb2, 0x1f, 0x16, 0xcd, 0x20, 0x6f, 0xd1, 0x2b, 0xb8, 0x1d, 0x15,
+	0x31, 0xae, 0x4f, 0x94, 0x50, 0x4d, 0x25, 0xf4, 0x76, 0x7c, 0x83, 0x88, 0x1c, 0xa5, 0xf4, 0x28,
+	0xe2, 0x8f, 0x02, 0x7a, 0xb8, 0x85, 0x1e, 0xc0, 0x4d, 0xec, 0xba, 0x8e, 0x6d, 0x61, 0x69, 0x33,
+	0x1a, 0x79, 0x15, 0x7a, 0xa6, 0x9a, 0xad, 0xef, 0x19, 0x87, 0x89, 0xcd, 0x90, 0x23, 0xd0, 0x3d,
+	0xa8, 0x70, 0x62, 0x31, 0x3e, 0x4e, 0xe0, 0xb3, 0x0a, 0x5f, 0xf6, 0xed, 0x31, 0xf4, 0x29, 0x1c,
+	0x48, 0xcc, 0x27, 0x44, 0x9a, 0xc1, 0x8d, 0x6d, 0x22, 0xf4, 0x9c, 0x4a, 0x3a, 0x5a, 0x4f, 0xba,
+	0x51, 0xf1, 0xc1, 0x67, 0x11, 0x16, 0x3d, 0x82, 0x92, 0xc3, 0x2c, 0xec, 0x84, 0xfc, 0x85, 0xbe,
+	0x5d, 0xd5, 0x36, 0xb0, 0x8b, 0x0a, 0x19, 0x49, 0x26, 0xa2, 0x92, 0x40, 0xbb, 0xfa, 0xce, 0x2a,
+	0x35, 0x54, 0x75, 0x40, 0x8d, 0x44, 0xfe, 0x1d, 0x94, 0x39, 0x99, 0x31, 0x49, 0x62, 0xee, 0xee,
+	0x46, 0x6e, 0xc9, 0x87, 0x46, 0xe4, 0x8f, 0xa1, 0x10, 0xdc, 0x59, 0x49, 0x30, 0xaf, 0xca, 0x0f,
+	0xbe, 0x69, 0xe0, 0x49, 0xf0, 0x19, 0xec, 0x73, 0xd7, 0x32, 0xaf, 0x08, 0x17, 0x36, 0xa3, 0x42,
+	0xdf, 0x53, 0xae, 0xef, 0xc6, 0xae, 0x0d, 0xd7, 0x0a, 0x53, 0xf8, 0x63, 0x00, 0x32, 0x0a, 0xdc,
+	0xb5, 0xc2, 0x05, 0xfa, 0x0c, 0x4a, 0x33, 0x7c, 0x6d, 0xbe, 0xe1, 0x78, 0x46, 0x4c, 0x61, 0xbf,
+	0x23, 0x3a, 0x54, 0xb5, 0x7a, 0xd1, 0xd8, 0x9f, 0xe1, 0xeb, 0x53, 0xcf, 0x38, 0xb2, 0xdf, 0x91,
+	0xda, 0xaf, 0x1a, 0x1c, 0x8d, 0x08, 0xbf, 0x22, 0x3c, 0xd6, 0x04, 0xf6, 0x76, 0x25, 0xe1, 0xe9,
+	0x55, 0xd4, 0xd2, 0xab, 0xf8, 0x04, 0x2a, 0x4b, 0x45, 0xf0, 0x8a, 0x98, 0xd9, 0x58, 0xc4, 0x72,
+	0xb2, 0x0c, 0x36, 0x11, 0xb5, 0xdf, 0x43, 0x75, 0xaf, 0x04, 0xe3, 0xa9, 0x7b, 0xa3, 0x00, 0xb5,
+	0xf7, 0x08, 0x70, 0x06, 0x87, 0x71, 0x4b, 0xb8, 0xd1, 0x95, 0x82, 0x98, 0x1e, 0xc7, 0x31, 0x6d,
+	0x38, 0xb5, 0x91, 0x92, 0x0f, 0xbf, 0xcb, 0x6f, 0x5c, 0xa6, 0x64, 0xea, 0x08, 0xf2, 0x36, 0x35,
+	0x5f, 0x2f, 0xfc, 0x81, 0xa1, 0xd5, 0xf7, 0x8d, 0x5d, 0x9b, 0x76, 0xbc, 0x65, 0x8a, 0xc6, 0x72,
+	0xff, 0x41, 0x63, 0xdb, 0x1f, 0xac, 0xb1, 0x55, 0x09, 0xed, 0xfc, 0x0f, 0x12, 0xda, 0x5d, 0x97,
+	0xd0, 0xf1, 0x14, 0xf4, 0x4d, 0xb9, 0x4a, 0x8e, 0xbc, 0x6d, 0x7f, 0xe4, 0x3d, 0x4a, 0x8e, 0xbc,
+	0x42, 0xeb, 0xd3, 0x44, 0x21, 0x36, 0xc9, 0x30, 0x31, 0x17, 0x6b, 0x5f, 0xc3, 0xad, 0x01, 0xb9,
+	0x8e, 0xa7, 0xdf, 0x0f, 0x44, 0x08, 0x3c, 0x51, 0x32, 0x49, 0x96, 0x40, 0x5b, 0x2a, 0x41, 0xed,
+	0x2f, 0x0d, 0x8a, 0x11, 0x85, 0x7b, 0xe0, 0x53, 0xd8, 0xb7, 0xd4, 0x1c, 0x35, 0x85, 0x57, 0x7f,
+	0x45, 0x28, 0xb4, 0x3e, 0x59, 0x91, 0xc5, 0xfa, 0xa8, 0xed, 0x6f, 0x19, 0x05, 0x9f, 0xa8, 0x00,
+	0x9e, 0x1f, 0xa1, 0xe2, 0x0e, 0xfc, 0x64, 0x52, 0xfd, 0xac, 0xcb, 0xcb, 0xf3, 0xe3, 0x13, 0x7d,
+	0x3f, 0x0f, 0x21, 0x47, 0xc9, 0xb5, 0x54, 0xda, 0x59, 0xe2, 0x6f, 0xb8, 0x6d, 0x7f, 0xcb, 0x50,
+	0x84, 0x4e, 0x01, 0xf6, 0x38, 0x79, 0x1b, 0xfc, 0x23, 0x7e, 0xcb, 0x42, 0x25, 0x79, 0x4f, 0x31,
+	0x77, 0x24, 0xfa, 0x0a, 0x0e, 0xd3, 0xda, 0x27, 0xf8, 0x0f, 0xdd, 0x48, 0xe9, 0x1e, 0xf4, 0x05,
+	0x94, 0x57, 0xfa, 0x3e, 0xf8, 0x43, 0x95, 0x96, 0xdb, 0xde, 0xcb, 0xf9, 0x94, 0x2c, 0xcc, 0x31,
+	0x96, 0x38, 0x94, 0xfd, 0x94, 0x2c, 0x4e, 0xb0, 0xc4, 0xe8, 0x21, 0x14, 0x5d, 0x42, 0x78, 0x3c,
+	0x94, 0x73, 0x1b, 0x87, 0xf2, 0xbe, 0x07, 0x5c, 0x9f, 0xc9, 0xff, 0x7e, 0x9c, 0xdf, 0x87, 0x83,
+	0x29, 0x21, 0xae, 0x69, 0x5d, 0x62, 0x4a, 0x89, 0x63, 0x32, 0x97, 0x50, 0xa5, 0xfb, 0xbc, 0x51,
+	0xf6, 0x36, 0xba, 0xbe, 0xfd, 0xdc, 0x25, 0x14, 0x9d, 0xc1, 0x81, 0x8a, 0x6f, 0xa9, 0x47, 0x76,
+	0x3f, 0xa4, 0x47, 0xca, 0x1e, 0xcf, 0x78, 0x6f, 0x9f, 0xe4, 0x53, 0x46, 0xed, 0xb3, 0x64, 0x6d,
+	0x46, 0x12, 0xcb, 0xb9, 0x7a, 0x0a, 0x59, 0x6c, 0x4c, 0x54, 0x2d, 0x8a, 0x86, 0xfa, 0x46, 0x3a,
+	0xec, 0x8e, 0x89, 0xc4, 0xb6, 0xfa, 0xc3, 0x7a, 0x49, 0x0f, 0x97, 0xb5, 0x3f, 0x34, 0x28, 0x2d,
+	0x95, 0xd7, 0xf5, 0x9e, 0x5a, 0x6c, 0x2e, 0xfd, 0xa3, 0x43, 0xd9, 0xef, 0xb1, 0xb9, 0x54, 0xc7,
+	0x0a, 0xf4, 0x39, 0x94, 0x54, 0x43, 0x98, 0x16, 0xa3, 0x62, 0x3e, 0x23, 0x63, 0xe5, 0xb2, 0x68,
+	0x14, 0x95, 0xb5, 0x1b, 0x18, 0x51, 0x0b, 0x76, 0xb8, 0x12, 0x4b, 0xa0, 0xbf, 0xe3, 0x94, 0xa7,
+	0x42, 0x20, 0x27, 0x23, 0x40, 0x7a, 0x1c, 0xa1, 0x2e, 0x11, 0x14, 0x36, 0x95, 0xe3, 0x5f, 0xd3,
+	0x08, 0x90, 0xf7, 0xbf, 0x87, 0x83, 0xb5, 0xa7, 0x07, 0xaa, 0xc1, 0x47, 0xfd, 0xf6, 0xe0, 0x64,
+	0xd4, 0x6f, 0x3f, 0xef, 0x99, 0x43, 0xe3, 0xfc, 0xe2, 0xbc, 0x7b, 0xfe, 0xc2, 0x7c, 0x39, 0x18,
+	0x0d, 0x7b, 0xdd, 0xb3, 0xd3, 0xb3, 0xde, 0x49, 0x65, 0x0b, 0xed, 0x42, 0xf6, 0xe2, 0xc5, 0xa8,
+	0xa2, 0xa1, 0x3c, 0xe4, 0xda, 0x2f, 0x2e, 0x46, 0x95, 0xcc, 0xfd, 0x1e, 0x94, 0x57, 0xde, 0x85,
+	0xa8, 0x0a, 0x77, 0x06, 0xbd, 0x8b, 0x9f, 0xce, 0x8d, 0xe7, 0xef, 0xf3, 0xd3, 0x1d, 0x56, 0x34,
+	0xef, 0xe3, 0xe5, 0xc9, 0xb0, 0x92, 0x69, 0xbd, 0x4a, 0x84, 0xc4, 0x47, 0xfe, 0x2b, 0x11, 0x9d,
+	0x42, 0xe1, 0x84, 0x45, 0x66, 0x74, 0x2b, 0x3d, 0x1d, 0x6f, 0x8f, 0xf5, 0x0d, 0x79, 0x72, 0x6b,
+	0x5b, 0x75, 0xed, 0x4b, 0xad, 0x33, 0x85, 0x9b, 0x36, 0xf3, 0x31, 0xd8, 0x91, 0xa2, 0x61, 0x53,
+	0x49, 0x38, 0xc5, 0x4e, 0xa7, 0x1c, 0xc3, 0x55, 0xf4, 0x43, 0xed, 0xe7, 0xa7, 0x13, 0xc6, 0x26,
+	0x0e, 0x69, 0x4c, 0x98, 0x83, 0xe9, 0xa4, 0xc1, 0xf8, 0xa4, 0xa9, 0x1e, 0xdf, 0x16, 0x27, 0x4a,
+	0xde, 0xd8, 0x11, 0x4d, 0xcf, 0x49, 0x33, 0x74, 0xd2, 0x54, 0xbd, 0xa9, 0x40, 0xe6, 0xc4, 0x72,
+	0x5f, 0xef, 0xa8, 0xf5, 0x83, 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, 0xc1, 0xf9, 0x9d, 0xf2, 0xd9,
+	0x0b, 0x00, 0x00,
+}
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ context.Context
+var _ grpc.ClientConn
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+const _ = grpc.SupportPackageIsVersion4
+
+// HandshakerServiceClient is the client API for HandshakerService service.
+//
+// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
+type HandshakerServiceClient interface {
+	// Handshaker service accepts a stream of handshaker request, returning a
+	// stream of handshaker response. Client is expected to send exactly one
+	// message with either client_start or server_start followed by one or more
+	// messages with next. Each time client sends a request, the handshaker
+	// service expects to respond. Client does not have to wait for service's
+	// response before sending next request.
+	DoHandshake(ctx context.Context, opts ...grpc.CallOption) (HandshakerService_DoHandshakeClient, error)
+}
+
+type handshakerServiceClient struct {
+	cc *grpc.ClientConn
+}
+
+func NewHandshakerServiceClient(cc *grpc.ClientConn) HandshakerServiceClient {
+	return &handshakerServiceClient{cc}
+}
+
+func (c *handshakerServiceClient) DoHandshake(ctx context.Context, opts ...grpc.CallOption) (HandshakerService_DoHandshakeClient, error) {
+	stream, err := c.cc.NewStream(ctx, &_HandshakerService_serviceDesc.Streams[0], "/grpc.gcp.HandshakerService/DoHandshake", opts...)
+	if err != nil {
+		return nil, err
+	}
+	x := &handshakerServiceDoHandshakeClient{stream}
+	return x, nil
+}
+
+type HandshakerService_DoHandshakeClient interface {
+	Send(*HandshakerReq) error
+	Recv() (*HandshakerResp, error)
+	grpc.ClientStream
+}
+
+type handshakerServiceDoHandshakeClient struct {
+	grpc.ClientStream
+}
+
+func (x *handshakerServiceDoHandshakeClient) Send(m *HandshakerReq) error {
+	return x.ClientStream.SendMsg(m)
+}
+
+func (x *handshakerServiceDoHandshakeClient) Recv() (*HandshakerResp, error) {
+	m := new(HandshakerResp)
+	if err := x.ClientStream.RecvMsg(m); err != nil {
+		return nil, err
+	}
+	return m, nil
+}
+
+// HandshakerServiceServer is the server API for HandshakerService service.
+type HandshakerServiceServer interface {
+	// Handshaker service accepts a stream of handshaker request, returning a
+	// stream of handshaker response. Client is expected to send exactly one
+	// message with either client_start or server_start followed by one or more
+	// messages with next. Each time client sends a request, the handshaker
+	// service expects to respond. Client does not have to wait for service's
+	// response before sending next request.
+	DoHandshake(HandshakerService_DoHandshakeServer) error
+}
+
+// UnimplementedHandshakerServiceServer can be embedded to have forward compatible implementations.
+type UnimplementedHandshakerServiceServer struct {
+}
+
+func (*UnimplementedHandshakerServiceServer) DoHandshake(srv HandshakerService_DoHandshakeServer) error {
+	return status.Errorf(codes.Unimplemented, "method DoHandshake not implemented")
+}
+
+func RegisterHandshakerServiceServer(s *grpc.Server, srv HandshakerServiceServer) {
+	s.RegisterService(&_HandshakerService_serviceDesc, srv)
+}
+
+func _HandshakerService_DoHandshake_Handler(srv interface{}, stream grpc.ServerStream) error {
+	return srv.(HandshakerServiceServer).DoHandshake(&handshakerServiceDoHandshakeServer{stream})
+}
+
+type HandshakerService_DoHandshakeServer interface {
+	Send(*HandshakerResp) error
+	Recv() (*HandshakerReq, error)
+	grpc.ServerStream
+}
+
+type handshakerServiceDoHandshakeServer struct {
+	grpc.ServerStream
+}
+
+func (x *handshakerServiceDoHandshakeServer) Send(m *HandshakerResp) error {
+	return x.ServerStream.SendMsg(m)
+}
+
+func (x *handshakerServiceDoHandshakeServer) Recv() (*HandshakerReq, error) {
+	m := new(HandshakerReq)
+	if err := x.ServerStream.RecvMsg(m); err != nil {
+		return nil, err
+	}
+	return m, nil
+}
+
+var _HandshakerService_serviceDesc = grpc.ServiceDesc{
+	ServiceName: "grpc.gcp.HandshakerService",
+	HandlerType: (*HandshakerServiceServer)(nil),
+	Methods:     []grpc.MethodDesc{},
+	Streams: []grpc.StreamDesc{
+		{
+			StreamName:    "DoHandshake",
+			Handler:       _HandshakerService_DoHandshake_Handler,
+			ServerStreams: true,
+			ClientStreams: true,
+		},
+	},
+	Metadata: "grpc/gcp/handshaker.proto",
+}

+ 184 - 0
vendor/google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp/transport_security_common.pb.go

@@ -0,0 +1,184 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: grpc/gcp/transport_security_common.proto
+
+package grpc_gcp
+
+import (
+	fmt "fmt"
+	proto "github.com/golang/protobuf/proto"
+	math "math"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
+
+// The security level of the created channel. The list is sorted in increasing
+// level of security. This order must always be maintained.
+type SecurityLevel int32
+
+const (
+	SecurityLevel_SECURITY_NONE         SecurityLevel = 0
+	SecurityLevel_INTEGRITY_ONLY        SecurityLevel = 1
+	SecurityLevel_INTEGRITY_AND_PRIVACY SecurityLevel = 2
+)
+
+var SecurityLevel_name = map[int32]string{
+	0: "SECURITY_NONE",
+	1: "INTEGRITY_ONLY",
+	2: "INTEGRITY_AND_PRIVACY",
+}
+
+var SecurityLevel_value = map[string]int32{
+	"SECURITY_NONE":         0,
+	"INTEGRITY_ONLY":        1,
+	"INTEGRITY_AND_PRIVACY": 2,
+}
+
+func (x SecurityLevel) String() string {
+	return proto.EnumName(SecurityLevel_name, int32(x))
+}
+
+func (SecurityLevel) EnumDescriptor() ([]byte, []int) {
+	return fileDescriptor_b97e31e3cc23582a, []int{0}
+}
+
+// Max and min supported RPC protocol versions.
+type RpcProtocolVersions struct {
+	// Maximum supported RPC version.
+	MaxRpcVersion *RpcProtocolVersions_Version `protobuf:"bytes,1,opt,name=max_rpc_version,json=maxRpcVersion,proto3" json:"max_rpc_version,omitempty"`
+	// Minimum supported RPC version.
+	MinRpcVersion        *RpcProtocolVersions_Version `protobuf:"bytes,2,opt,name=min_rpc_version,json=minRpcVersion,proto3" json:"min_rpc_version,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}                     `json:"-"`
+	XXX_unrecognized     []byte                       `json:"-"`
+	XXX_sizecache        int32                        `json:"-"`
+}
+
+func (m *RpcProtocolVersions) Reset()         { *m = RpcProtocolVersions{} }
+func (m *RpcProtocolVersions) String() string { return proto.CompactTextString(m) }
+func (*RpcProtocolVersions) ProtoMessage()    {}
+func (*RpcProtocolVersions) Descriptor() ([]byte, []int) {
+	return fileDescriptor_b97e31e3cc23582a, []int{0}
+}
+
+func (m *RpcProtocolVersions) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_RpcProtocolVersions.Unmarshal(m, b)
+}
+func (m *RpcProtocolVersions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_RpcProtocolVersions.Marshal(b, m, deterministic)
+}
+func (m *RpcProtocolVersions) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_RpcProtocolVersions.Merge(m, src)
+}
+func (m *RpcProtocolVersions) XXX_Size() int {
+	return xxx_messageInfo_RpcProtocolVersions.Size(m)
+}
+func (m *RpcProtocolVersions) XXX_DiscardUnknown() {
+	xxx_messageInfo_RpcProtocolVersions.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_RpcProtocolVersions proto.InternalMessageInfo
+
+func (m *RpcProtocolVersions) GetMaxRpcVersion() *RpcProtocolVersions_Version {
+	if m != nil {
+		return m.MaxRpcVersion
+	}
+	return nil
+}
+
+func (m *RpcProtocolVersions) GetMinRpcVersion() *RpcProtocolVersions_Version {
+	if m != nil {
+		return m.MinRpcVersion
+	}
+	return nil
+}
+
+// RPC version contains a major version and a minor version.
+type RpcProtocolVersions_Version struct {
+	Major                uint32   `protobuf:"varint,1,opt,name=major,proto3" json:"major,omitempty"`
+	Minor                uint32   `protobuf:"varint,2,opt,name=minor,proto3" json:"minor,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *RpcProtocolVersions_Version) Reset()         { *m = RpcProtocolVersions_Version{} }
+func (m *RpcProtocolVersions_Version) String() string { return proto.CompactTextString(m) }
+func (*RpcProtocolVersions_Version) ProtoMessage()    {}
+func (*RpcProtocolVersions_Version) Descriptor() ([]byte, []int) {
+	return fileDescriptor_b97e31e3cc23582a, []int{0, 0}
+}
+
+func (m *RpcProtocolVersions_Version) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_RpcProtocolVersions_Version.Unmarshal(m, b)
+}
+func (m *RpcProtocolVersions_Version) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_RpcProtocolVersions_Version.Marshal(b, m, deterministic)
+}
+func (m *RpcProtocolVersions_Version) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_RpcProtocolVersions_Version.Merge(m, src)
+}
+func (m *RpcProtocolVersions_Version) XXX_Size() int {
+	return xxx_messageInfo_RpcProtocolVersions_Version.Size(m)
+}
+func (m *RpcProtocolVersions_Version) XXX_DiscardUnknown() {
+	xxx_messageInfo_RpcProtocolVersions_Version.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_RpcProtocolVersions_Version proto.InternalMessageInfo
+
+func (m *RpcProtocolVersions_Version) GetMajor() uint32 {
+	if m != nil {
+		return m.Major
+	}
+	return 0
+}
+
+func (m *RpcProtocolVersions_Version) GetMinor() uint32 {
+	if m != nil {
+		return m.Minor
+	}
+	return 0
+}
+
+func init() {
+	proto.RegisterEnum("grpc.gcp.SecurityLevel", SecurityLevel_name, SecurityLevel_value)
+	proto.RegisterType((*RpcProtocolVersions)(nil), "grpc.gcp.RpcProtocolVersions")
+	proto.RegisterType((*RpcProtocolVersions_Version)(nil), "grpc.gcp.RpcProtocolVersions.Version")
+}
+
+func init() {
+	proto.RegisterFile("grpc/gcp/transport_security_common.proto", fileDescriptor_b97e31e3cc23582a)
+}
+
+var fileDescriptor_b97e31e3cc23582a = []byte{
+	// 323 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x91, 0x41, 0x4b, 0x3b, 0x31,
+	0x10, 0xc5, 0xff, 0x5b, 0xf8, 0xab, 0x44, 0x56, 0xeb, 0x6a, 0x41, 0xc5, 0x83, 0x08, 0x42, 0xf1,
+	0x90, 0x05, 0xc5, 0xb3, 0xb4, 0xb5, 0x48, 0xa1, 0x6e, 0xeb, 0xb6, 0x16, 0xea, 0x25, 0xc4, 0x18,
+	0x42, 0x24, 0x9b, 0x09, 0xb3, 0xb1, 0xd4, 0xaf, 0xec, 0xa7, 0x90, 0x4d, 0xbb, 0x14, 0xc1, 0x8b,
+	0xb7, 0xbc, 0xc7, 0xcc, 0x6f, 0x32, 0xf3, 0x48, 0x5b, 0xa1, 0x13, 0xa9, 0x12, 0x2e, 0xf5, 0xc8,
+	0x6d, 0xe9, 0x00, 0x3d, 0x2b, 0xa5, 0xf8, 0x40, 0xed, 0x3f, 0x99, 0x80, 0xa2, 0x00, 0x4b, 0x1d,
+	0x82, 0x87, 0x64, 0xa7, 0xaa, 0xa4, 0x4a, 0xb8, 0x8b, 0xaf, 0x88, 0x1c, 0xe6, 0x4e, 0x8c, 0x2b,
+	0x5b, 0x80, 0x99, 0x49, 0x2c, 0x35, 0xd8, 0x32, 0x79, 0x24, 0xfb, 0x05, 0x5f, 0x32, 0x74, 0x82,
+	0x2d, 0x56, 0xde, 0x71, 0x74, 0x1e, 0xb5, 0x77, 0xaf, 0x2f, 0x69, 0xdd, 0x4b, 0x7f, 0xe9, 0xa3,
+	0xeb, 0x47, 0x1e, 0x17, 0x7c, 0x99, 0x3b, 0xb1, 0x96, 0x01, 0xa7, 0xed, 0x0f, 0x5c, 0xe3, 0x6f,
+	0x38, 0x6d, 0x37, 0xb8, 0xd3, 0x5b, 0xb2, 0x5d, 0x93, 0x8f, 0xc8, 0xff, 0x82, 0xbf, 0x03, 0x86,
+	0xef, 0xc5, 0xf9, 0x4a, 0x04, 0x57, 0x5b, 0xc0, 0x30, 0xa5, 0x72, 0x2b, 0x71, 0xf5, 0x44, 0xe2,
+	0xc9, 0xfa, 0x1e, 0x43, 0xb9, 0x90, 0x26, 0x39, 0x20, 0xf1, 0xa4, 0xdf, 0x7b, 0xce, 0x07, 0xd3,
+	0x39, 0xcb, 0x46, 0x59, 0xbf, 0xf9, 0x2f, 0x49, 0xc8, 0xde, 0x20, 0x9b, 0xf6, 0x1f, 0x82, 0x37,
+	0xca, 0x86, 0xf3, 0x66, 0x94, 0x9c, 0x90, 0xd6, 0xc6, 0xeb, 0x64, 0xf7, 0x6c, 0x9c, 0x0f, 0x66,
+	0x9d, 0xde, 0xbc, 0xd9, 0xe8, 0x2e, 0x49, 0x4b, 0xc3, 0x6a, 0x07, 0x6e, 0x7c, 0x49, 0xb5, 0xf5,
+	0x12, 0x2d, 0x37, 0xdd, 0xb3, 0x69, 0x9d, 0x41, 0x3d, 0xb2, 0x17, 0x12, 0x08, 0x2b, 0x8e, 0xa3,
+	0x97, 0x3b, 0x05, 0xa0, 0x8c, 0xa4, 0x0a, 0x0c, 0xb7, 0x8a, 0x02, 0xaa, 0x34, 0xc4, 0x27, 0x50,
+	0xbe, 0x49, 0xeb, 0x35, 0x37, 0x65, 0x5a, 0x11, 0xd3, 0x9a, 0x98, 0x86, 0xe8, 0x42, 0x11, 0x53,
+	0xc2, 0xbd, 0x6e, 0x05, 0x7d, 0xf3, 0x1d, 0x00, 0x00, 0xff, 0xff, 0x31, 0x14, 0xb4, 0x11, 0xf6,
+	0x01, 0x00, 0x00,
+}

+ 163 - 0
vendor/google.golang.org/grpc/credentials/alts/utils.go

@@ -0,0 +1,163 @@
+/*
+ *
+ * Copyright 2018 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package alts
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"log"
+	"os"
+	"os/exec"
+	"regexp"
+	"runtime"
+	"strings"
+
+	"google.golang.org/grpc/codes"
+	"google.golang.org/grpc/peer"
+	"google.golang.org/grpc/status"
+)
+
+const (
+	linuxProductNameFile     = "/sys/class/dmi/id/product_name"
+	windowsCheckCommand      = "powershell.exe"
+	windowsCheckCommandArgs  = "Get-WmiObject -Class Win32_BIOS"
+	powershellOutputFilter   = "Manufacturer"
+	windowsManufacturerRegex = ":(.*)"
+)
+
+type platformError string
+
+func (k platformError) Error() string {
+	return fmt.Sprintf("%s is not supported", string(k))
+}
+
+var (
+	// The following two variables will be reassigned in tests.
+	runningOS          = runtime.GOOS
+	manufacturerReader = func() (io.Reader, error) {
+		switch runningOS {
+		case "linux":
+			return os.Open(linuxProductNameFile)
+		case "windows":
+			cmd := exec.Command(windowsCheckCommand, windowsCheckCommandArgs)
+			out, err := cmd.Output()
+			if err != nil {
+				return nil, err
+			}
+
+			for _, line := range strings.Split(strings.TrimSuffix(string(out), "\n"), "\n") {
+				if strings.HasPrefix(line, powershellOutputFilter) {
+					re := regexp.MustCompile(windowsManufacturerRegex)
+					name := re.FindString(line)
+					name = strings.TrimLeft(name, ":")
+					return strings.NewReader(name), nil
+				}
+			}
+
+			return nil, errors.New("cannot determine the machine's manufacturer")
+		default:
+			return nil, platformError(runningOS)
+		}
+	}
+	vmOnGCP bool
+)
+
+// isRunningOnGCP checks whether the local system, without doing a network request is
+// running on GCP.
+func isRunningOnGCP() bool {
+	manufacturer, err := readManufacturer()
+	if os.IsNotExist(err) {
+		return false
+	}
+	if err != nil {
+		log.Fatalf("failure to read manufacturer information: %v", err)
+	}
+	name := string(manufacturer)
+	switch runningOS {
+	case "linux":
+		name = strings.TrimSpace(name)
+		return name == "Google" || name == "Google Compute Engine"
+	case "windows":
+		name = strings.Replace(name, " ", "", -1)
+		name = strings.Replace(name, "\n", "", -1)
+		name = strings.Replace(name, "\r", "", -1)
+		return name == "Google"
+	default:
+		log.Fatal(platformError(runningOS))
+	}
+	return false
+}
+
+func readManufacturer() ([]byte, error) {
+	reader, err := manufacturerReader()
+	if err != nil {
+		return nil, err
+	}
+	if reader == nil {
+		return nil, errors.New("got nil reader")
+	}
+	manufacturer, err := ioutil.ReadAll(reader)
+	if err != nil {
+		return nil, fmt.Errorf("failed reading %v: %v", linuxProductNameFile, err)
+	}
+	return manufacturer, nil
+}
+
+// AuthInfoFromContext extracts the alts.AuthInfo object from the given context,
+// if it exists. This API should be used by gRPC server RPC handlers to get
+// information about the communicating peer. For client-side, use grpc.Peer()
+// CallOption.
+func AuthInfoFromContext(ctx context.Context) (AuthInfo, error) {
+	p, ok := peer.FromContext(ctx)
+	if !ok {
+		return nil, errors.New("no Peer found in Context")
+	}
+	return AuthInfoFromPeer(p)
+}
+
+// AuthInfoFromPeer extracts the alts.AuthInfo object from the given peer, if it
+// exists. This API should be used by gRPC clients after obtaining a peer object
+// using the grpc.Peer() CallOption.
+func AuthInfoFromPeer(p *peer.Peer) (AuthInfo, error) {
+	altsAuthInfo, ok := p.AuthInfo.(AuthInfo)
+	if !ok {
+		return nil, errors.New("no alts.AuthInfo found in Peer")
+	}
+	return altsAuthInfo, nil
+}
+
+// ClientAuthorizationCheck checks whether the client is authorized to access
+// the requested resources based on the given expected client service accounts.
+// This API should be used by gRPC server RPC handlers. This API should not be
+// used by clients.
+func ClientAuthorizationCheck(ctx context.Context, expectedServiceAccounts []string) error {
+	authInfo, err := AuthInfoFromContext(ctx)
+	if err != nil {
+		return status.Newf(codes.PermissionDenied, "The context is not an ALTS-compatible context: %v", err).Err()
+	}
+	for _, sa := range expectedServiceAccounts {
+		if authInfo.PeerServiceAccount() == sa {
+			return nil
+		}
+	}
+	return status.Newf(codes.PermissionDenied, "Client %v is not authorized", authInfo.PeerServiceAccount()).Err()
+}

+ 125 - 0
vendor/google.golang.org/grpc/credentials/google/google.go

@@ -0,0 +1,125 @@
+/*
+ *
+ * Copyright 2018 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Package google defines credentials for google cloud services.
+package google
+
+import (
+	"context"
+	"fmt"
+	"time"
+
+	"google.golang.org/grpc/credentials"
+	"google.golang.org/grpc/credentials/alts"
+	"google.golang.org/grpc/credentials/oauth"
+	"google.golang.org/grpc/grpclog"
+	"google.golang.org/grpc/internal"
+)
+
+const tokenRequestTimeout = 30 * time.Second
+
+// NewDefaultCredentials returns a credentials bundle that is configured to work
+// with google services.
+//
+// This API is experimental.
+func NewDefaultCredentials() credentials.Bundle {
+	c := &creds{
+		newPerRPCCreds: func() credentials.PerRPCCredentials {
+			ctx, cancel := context.WithTimeout(context.Background(), tokenRequestTimeout)
+			defer cancel()
+			perRPCCreds, err := oauth.NewApplicationDefault(ctx)
+			if err != nil {
+				grpclog.Warningf("google default creds: failed to create application oauth: %v", err)
+			}
+			return perRPCCreds
+		},
+	}
+	bundle, err := c.NewWithMode(internal.CredsBundleModeFallback)
+	if err != nil {
+		grpclog.Warningf("google default creds: failed to create new creds: %v", err)
+	}
+	return bundle
+}
+
+// NewComputeEngineCredentials returns a credentials bundle that is configured to work
+// with google services. This API must only be used when running on GCE. Authentication configured
+// by this API represents the GCE VM's default service account.
+//
+// This API is experimental.
+func NewComputeEngineCredentials() credentials.Bundle {
+	c := &creds{
+		newPerRPCCreds: func() credentials.PerRPCCredentials {
+			return oauth.NewComputeEngine()
+		},
+	}
+	bundle, err := c.NewWithMode(internal.CredsBundleModeFallback)
+	if err != nil {
+		grpclog.Warningf("compute engine creds: failed to create new creds: %v", err)
+	}
+	return bundle
+}
+
+// creds implements credentials.Bundle.
+type creds struct {
+	// Supported modes are defined in internal/internal.go.
+	mode string
+	// The transport credentials associated with this bundle.
+	transportCreds credentials.TransportCredentials
+	// The per RPC credentials associated with this bundle.
+	perRPCCreds credentials.PerRPCCredentials
+	// Creates new per RPC credentials
+	newPerRPCCreds func() credentials.PerRPCCredentials
+}
+
+func (c *creds) TransportCredentials() credentials.TransportCredentials {
+	return c.transportCreds
+}
+
+func (c *creds) PerRPCCredentials() credentials.PerRPCCredentials {
+	if c == nil {
+		return nil
+	}
+	return c.perRPCCreds
+}
+
+// NewWithMode should make a copy of Bundle, and switch mode. Modifying the
+// existing Bundle may cause races.
+func (c *creds) NewWithMode(mode string) (credentials.Bundle, error) {
+	newCreds := &creds{
+		mode:           mode,
+		newPerRPCCreds: c.newPerRPCCreds,
+	}
+
+	// Create transport credentials.
+	switch mode {
+	case internal.CredsBundleModeFallback:
+		newCreds.transportCreds = credentials.NewTLS(nil)
+	case internal.CredsBundleModeBackendFromBalancer, internal.CredsBundleModeBalancer:
+		// Only the clients can use google default credentials, so we only need
+		// to create new ALTS client creds here.
+		newCreds.transportCreds = alts.NewClientCreds(alts.DefaultClientOptions())
+	default:
+		return nil, fmt.Errorf("unsupported mode: %v", mode)
+	}
+
+	if mode == internal.CredsBundleModeFallback || mode == internal.CredsBundleModeBackendFromBalancer {
+		newCreds.perRPCCreds = newCreds.newPerRPCCreds()
+	}
+
+	return newCreds, nil
+}