Bumping k8s dependencies to 1.13
This commit is contained in:
365
vendor/google.golang.org/grpc/credentials/alts/internal/handshaker/handshaker.go
generated
vendored
Normal file
365
vendor/google.golang.org/grpc/credentials/alts/internal/handshaker/handshaker.go
generated
vendored
Normal file
@@ -0,0 +1,365 @@
|
||||
/*
|
||||
*
|
||||
* 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 (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"sync"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
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")
|
||||
)
|
||||
|
||||
func init() {
|
||||
for protocol, f := range altsRecordFuncs {
|
||||
if err := conn.RegisterProtocol(protocol, f); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func acquire(n int64) bool {
|
||||
mu.Lock()
|
||||
success := maxPendingHandshakes-concurrentHandshakes >= n
|
||||
if success {
|
||||
concurrentHandshakes += n
|
||||
}
|
||||
mu.Unlock()
|
||||
return success
|
||||
}
|
||||
|
||||
func release(n int64) {
|
||||
mu.Lock()
|
||||
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.FailFast(false))
|
||||
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.FailFast(false))
|
||||
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(1) {
|
||||
return nil, nil, errDropped
|
||||
}
|
||||
defer release(1)
|
||||
|
||||
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(1) {
|
||||
return nil, nil, errDropped
|
||||
}
|
||||
defer release(1)
|
||||
|
||||
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 {
|
||||
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]...)
|
||||
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 n == 0 {
|
||||
extra = nil
|
||||
} else {
|
||||
extra = buf[resp.GetBytesConsumed():n]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Close terminates the Handshaker. It should be called when the caller obtains
|
||||
// the secure connection.
|
||||
func (h *altsHandshaker) Close() {
|
||||
h.stream.CloseSend()
|
||||
}
|
261
vendor/google.golang.org/grpc/credentials/alts/internal/handshaker/handshaker_test.go
generated
vendored
Normal file
261
vendor/google.golang.org/grpc/credentials/alts/internal/handshaker/handshaker_test.go
generated
vendored
Normal file
@@ -0,0 +1,261 @@
|
||||
/*
|
||||
*
|
||||
* 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
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
grpc "google.golang.org/grpc"
|
||||
core "google.golang.org/grpc/credentials/alts/internal"
|
||||
altspb "google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp"
|
||||
"google.golang.org/grpc/credentials/alts/internal/testutil"
|
||||
)
|
||||
|
||||
var (
|
||||
testAppProtocols = []string{"grpc"}
|
||||
testRecordProtocol = rekeyRecordProtocolName
|
||||
testKey = []byte{
|
||||
// 44 arbitrary bytes.
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xd2, 0x4c, 0xce, 0x4f, 0x49,
|
||||
0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xd2, 0x4c, 0xce, 0x4f, 0x49, 0x1f, 0x8b,
|
||||
0xd2, 0x4c, 0xce, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2,
|
||||
}
|
||||
testServiceAccount = "test_service_account"
|
||||
testTargetServiceAccounts = []string{testServiceAccount}
|
||||
testClientIdentity = &altspb.Identity{
|
||||
IdentityOneof: &altspb.Identity_Hostname{
|
||||
Hostname: "i_am_a_client",
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
// testRPCStream mimics a altspb.HandshakerService_DoHandshakeClient object.
|
||||
type testRPCStream struct {
|
||||
grpc.ClientStream
|
||||
t *testing.T
|
||||
isClient bool
|
||||
// The resp expected to be returned by Recv(). Make sure this is set to
|
||||
// the content the test requires before Recv() is invoked.
|
||||
recvBuf *altspb.HandshakerResp
|
||||
// false if it is the first access to Handshaker service on Envelope.
|
||||
first bool
|
||||
// useful for testing concurrent calls.
|
||||
delay time.Duration
|
||||
}
|
||||
|
||||
func (t *testRPCStream) Recv() (*altspb.HandshakerResp, error) {
|
||||
resp := t.recvBuf
|
||||
t.recvBuf = nil
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (t *testRPCStream) Send(req *altspb.HandshakerReq) error {
|
||||
var resp *altspb.HandshakerResp
|
||||
if !t.first {
|
||||
// Generate the bytes to be returned by Recv() for the initial
|
||||
// handshaking.
|
||||
t.first = true
|
||||
if t.isClient {
|
||||
resp = &altspb.HandshakerResp{
|
||||
OutFrames: testutil.MakeFrame("ClientInit"),
|
||||
// Simulate consuming ServerInit.
|
||||
BytesConsumed: 14,
|
||||
}
|
||||
} else {
|
||||
resp = &altspb.HandshakerResp{
|
||||
OutFrames: testutil.MakeFrame("ServerInit"),
|
||||
// Simulate consuming ClientInit.
|
||||
BytesConsumed: 14,
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Add delay to test concurrent calls.
|
||||
cleanup := stat.Update()
|
||||
defer cleanup()
|
||||
time.Sleep(t.delay)
|
||||
|
||||
// Generate the response to be returned by Recv() for the
|
||||
// follow-up handshaking.
|
||||
result := &altspb.HandshakerResult{
|
||||
RecordProtocol: testRecordProtocol,
|
||||
KeyData: testKey,
|
||||
}
|
||||
resp = &altspb.HandshakerResp{
|
||||
Result: result,
|
||||
// Simulate consuming ClientFinished or ServerFinished.
|
||||
BytesConsumed: 18,
|
||||
}
|
||||
}
|
||||
t.recvBuf = resp
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *testRPCStream) CloseSend() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
var stat testutil.Stats
|
||||
|
||||
func TestClientHandshake(t *testing.T) {
|
||||
for _, testCase := range []struct {
|
||||
delay time.Duration
|
||||
numberOfHandshakes int
|
||||
}{
|
||||
{0 * time.Millisecond, 1},
|
||||
{100 * time.Millisecond, 10 * maxPendingHandshakes},
|
||||
} {
|
||||
errc := make(chan error)
|
||||
stat.Reset()
|
||||
for i := 0; i < testCase.numberOfHandshakes; i++ {
|
||||
stream := &testRPCStream{
|
||||
t: t,
|
||||
isClient: true,
|
||||
}
|
||||
// Preload the inbound frames.
|
||||
f1 := testutil.MakeFrame("ServerInit")
|
||||
f2 := testutil.MakeFrame("ServerFinished")
|
||||
in := bytes.NewBuffer(f1)
|
||||
in.Write(f2)
|
||||
out := new(bytes.Buffer)
|
||||
tc := testutil.NewTestConn(in, out)
|
||||
chs := &altsHandshaker{
|
||||
stream: stream,
|
||||
conn: tc,
|
||||
clientOpts: &ClientHandshakerOptions{
|
||||
TargetServiceAccounts: testTargetServiceAccounts,
|
||||
ClientIdentity: testClientIdentity,
|
||||
},
|
||||
side: core.ClientSide,
|
||||
}
|
||||
go func() {
|
||||
_, context, err := chs.ClientHandshake(context.Background())
|
||||
if err == nil && context == nil {
|
||||
panic("expected non-nil ALTS context")
|
||||
}
|
||||
errc <- err
|
||||
chs.Close()
|
||||
}()
|
||||
}
|
||||
|
||||
// Ensure all errors are expected.
|
||||
for i := 0; i < testCase.numberOfHandshakes; i++ {
|
||||
if err := <-errc; err != nil && err != errDropped {
|
||||
t.Errorf("ClientHandshake() = _, %v, want _, <nil> or %v", err, errDropped)
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that there are no concurrent calls more than the limit.
|
||||
if stat.MaxConcurrentCalls > maxPendingHandshakes {
|
||||
t.Errorf("Observed %d concurrent handshakes; want <= %d", stat.MaxConcurrentCalls, maxPendingHandshakes)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestServerHandshake(t *testing.T) {
|
||||
for _, testCase := range []struct {
|
||||
delay time.Duration
|
||||
numberOfHandshakes int
|
||||
}{
|
||||
{0 * time.Millisecond, 1},
|
||||
{100 * time.Millisecond, 10 * maxPendingHandshakes},
|
||||
} {
|
||||
errc := make(chan error)
|
||||
stat.Reset()
|
||||
for i := 0; i < testCase.numberOfHandshakes; i++ {
|
||||
stream := &testRPCStream{
|
||||
t: t,
|
||||
isClient: false,
|
||||
}
|
||||
// Preload the inbound frames.
|
||||
f1 := testutil.MakeFrame("ClientInit")
|
||||
f2 := testutil.MakeFrame("ClientFinished")
|
||||
in := bytes.NewBuffer(f1)
|
||||
in.Write(f2)
|
||||
out := new(bytes.Buffer)
|
||||
tc := testutil.NewTestConn(in, out)
|
||||
shs := &altsHandshaker{
|
||||
stream: stream,
|
||||
conn: tc,
|
||||
serverOpts: DefaultServerHandshakerOptions(),
|
||||
side: core.ServerSide,
|
||||
}
|
||||
go func() {
|
||||
_, context, err := shs.ServerHandshake(context.Background())
|
||||
if err == nil && context == nil {
|
||||
panic("expected non-nil ALTS context")
|
||||
}
|
||||
errc <- err
|
||||
shs.Close()
|
||||
}()
|
||||
}
|
||||
|
||||
// Ensure all errors are expected.
|
||||
for i := 0; i < testCase.numberOfHandshakes; i++ {
|
||||
if err := <-errc; err != nil && err != errDropped {
|
||||
t.Errorf("ServerHandshake() = _, %v, want _, <nil> or %v", err, errDropped)
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that there are no concurrent calls more than the limit.
|
||||
if stat.MaxConcurrentCalls > maxPendingHandshakes {
|
||||
t.Errorf("Observed %d concurrent handshakes; want <= %d", stat.MaxConcurrentCalls, maxPendingHandshakes)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// testUnresponsiveRPCStream is used for testing the PeerNotResponding case.
|
||||
type testUnresponsiveRPCStream struct {
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
func (t *testUnresponsiveRPCStream) Recv() (*altspb.HandshakerResp, error) {
|
||||
return &altspb.HandshakerResp{}, nil
|
||||
}
|
||||
|
||||
func (t *testUnresponsiveRPCStream) Send(req *altspb.HandshakerReq) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *testUnresponsiveRPCStream) CloseSend() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestPeerNotResponding(t *testing.T) {
|
||||
stream := &testUnresponsiveRPCStream{}
|
||||
chs := &altsHandshaker{
|
||||
stream: stream,
|
||||
conn: testutil.NewUnresponsiveTestConn(),
|
||||
clientOpts: &ClientHandshakerOptions{
|
||||
TargetServiceAccounts: testTargetServiceAccounts,
|
||||
ClientIdentity: testClientIdentity,
|
||||
},
|
||||
side: core.ClientSide,
|
||||
}
|
||||
_, context, err := chs.ClientHandshake(context.Background())
|
||||
chs.Close()
|
||||
if context != nil {
|
||||
t.Error("expected non-nil ALTS context")
|
||||
}
|
||||
if got, want := err, core.PeerNotRespondingError; got != want {
|
||||
t.Errorf("ClientHandshake() = %v, want %v", got, want)
|
||||
}
|
||||
}
|
56
vendor/google.golang.org/grpc/credentials/alts/internal/handshaker/service/service.go
generated
vendored
Normal file
56
vendor/google.golang.org/grpc/credentials/alts/internal/handshaker/service/service.go
generated
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
*
|
||||
* 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
|
||||
)
|
||||
|
||||
type dialer func(target string, opts ...grpc.DialOption) (*grpc.ClientConn, error)
|
||||
|
||||
// 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
|
||||
}
|
69
vendor/google.golang.org/grpc/credentials/alts/internal/handshaker/service/service_test.go
generated
vendored
Normal file
69
vendor/google.golang.org/grpc/credentials/alts/internal/handshaker/service/service_test.go
generated
vendored
Normal file
@@ -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.
|
||||
*
|
||||
*/
|
||||
|
||||
package service
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
grpc "google.golang.org/grpc"
|
||||
)
|
||||
|
||||
const (
|
||||
// The address is irrelevant in this test.
|
||||
testAddress = "some_address"
|
||||
)
|
||||
|
||||
func TestDial(t *testing.T) {
|
||||
defer func() func() {
|
||||
temp := hsDialer
|
||||
hsDialer = func(target string, opts ...grpc.DialOption) (*grpc.ClientConn, error) {
|
||||
return &grpc.ClientConn{}, nil
|
||||
}
|
||||
return func() {
|
||||
hsDialer = temp
|
||||
}
|
||||
}()
|
||||
|
||||
// Ensure that hsConn is nil at first.
|
||||
hsConn = nil
|
||||
|
||||
// First call to Dial, it should create set hsConn.
|
||||
conn1, err := Dial(testAddress)
|
||||
if err != nil {
|
||||
t.Fatalf("first call to Dial failed: %v", err)
|
||||
}
|
||||
if conn1 == nil {
|
||||
t.Fatal("first call to Dial(_)=(nil, _), want not nil")
|
||||
}
|
||||
if got, want := hsConn, conn1; got != want {
|
||||
t.Fatalf("hsConn=%v, want %v", got, want)
|
||||
}
|
||||
|
||||
// Second call to Dial should return conn1 above.
|
||||
conn2, err := Dial(testAddress)
|
||||
if err != nil {
|
||||
t.Fatalf("second call to Dial(_) failed: %v", err)
|
||||
}
|
||||
if got, want := conn2, conn1; got != want {
|
||||
t.Fatalf("second call to Dial(_)=(%v, _), want (%v,. _)", got, want)
|
||||
}
|
||||
if got, want := hsConn, conn1; got != want {
|
||||
t.Fatalf("hsConn=%v, want %v", got, want)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user