working-config-otel
Signed-off-by: Davanum Srinivas <davanum@gmail.com>
This commit is contained in:
167
vendor/github.com/google/s2a-go/fallback/s2a_fallback.go
generated
vendored
Normal file
167
vendor/github.com/google/s2a-go/fallback/s2a_fallback.go
generated
vendored
Normal file
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2023 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
|
||||
*
|
||||
* https://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 fallback provides default implementations of fallback options when S2A fails.
|
||||
package fallback
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"google.golang.org/grpc/credentials"
|
||||
"google.golang.org/grpc/grpclog"
|
||||
)
|
||||
|
||||
const (
|
||||
alpnProtoStrH2 = "h2"
|
||||
alpnProtoStrHTTP = "http/1.1"
|
||||
defaultHTTPSPort = "443"
|
||||
)
|
||||
|
||||
// FallbackTLSConfigGRPC is a tls.Config used by the DefaultFallbackClientHandshakeFunc function.
|
||||
// It supports GRPC use case, thus the alpn is set to 'h2'.
|
||||
var FallbackTLSConfigGRPC = tls.Config{
|
||||
MinVersion: tls.VersionTLS13,
|
||||
ClientSessionCache: nil,
|
||||
NextProtos: []string{alpnProtoStrH2},
|
||||
}
|
||||
|
||||
// FallbackTLSConfigHTTP is a tls.Config used by the DefaultFallbackDialerAndAddress func.
|
||||
// It supports the HTTP use case and the alpn is set to both 'http/1.1' and 'h2'.
|
||||
var FallbackTLSConfigHTTP = tls.Config{
|
||||
MinVersion: tls.VersionTLS13,
|
||||
ClientSessionCache: nil,
|
||||
NextProtos: []string{alpnProtoStrH2, alpnProtoStrHTTP},
|
||||
}
|
||||
|
||||
// ClientHandshake establishes a TLS connection and returns it, plus its auth info.
|
||||
// Inputs:
|
||||
//
|
||||
// targetServer: the server attempted with S2A.
|
||||
// conn: the tcp connection to the server at address targetServer that was passed into S2A's ClientHandshake func.
|
||||
// If fallback is successful, the `conn` should be closed.
|
||||
// err: the error encountered when performing the client-side TLS handshake with S2A.
|
||||
type ClientHandshake func(ctx context.Context, targetServer string, conn net.Conn, err error) (net.Conn, credentials.AuthInfo, error)
|
||||
|
||||
// DefaultFallbackClientHandshakeFunc returns a ClientHandshake function,
|
||||
// which establishes a TLS connection to the provided fallbackAddr, returns the new connection and its auth info.
|
||||
// Example use:
|
||||
//
|
||||
// transportCreds, _ = s2a.NewClientCreds(&s2a.ClientOptions{
|
||||
// S2AAddress: s2aAddress,
|
||||
// FallbackOpts: &s2a.FallbackOptions{ // optional
|
||||
// FallbackClientHandshakeFunc: fallback.DefaultFallbackClientHandshakeFunc(fallbackAddr),
|
||||
// },
|
||||
// })
|
||||
//
|
||||
// The fallback server's certificate must be verifiable using OS root store.
|
||||
// The fallbackAddr is expected to be a network address, e.g. example.com:port. If port is not specified,
|
||||
// it uses default port 443.
|
||||
// In the returned function's TLS config, ClientSessionCache is explicitly set to nil to disable TLS resumption,
|
||||
// and min TLS version is set to 1.3.
|
||||
func DefaultFallbackClientHandshakeFunc(fallbackAddr string) (ClientHandshake, error) {
|
||||
var fallbackDialer = tls.Dialer{Config: &FallbackTLSConfigGRPC}
|
||||
return defaultFallbackClientHandshakeFuncInternal(fallbackAddr, fallbackDialer.DialContext)
|
||||
}
|
||||
|
||||
func defaultFallbackClientHandshakeFuncInternal(fallbackAddr string, dialContextFunc func(context.Context, string, string) (net.Conn, error)) (ClientHandshake, error) {
|
||||
fallbackServerAddr, err := processFallbackAddr(fallbackAddr)
|
||||
if err != nil {
|
||||
if grpclog.V(1) {
|
||||
grpclog.Infof("error processing fallback address [%s]: %v", fallbackAddr, err)
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return func(ctx context.Context, targetServer string, conn net.Conn, s2aErr error) (net.Conn, credentials.AuthInfo, error) {
|
||||
fbConn, fbErr := dialContextFunc(ctx, "tcp", fallbackServerAddr)
|
||||
if fbErr != nil {
|
||||
grpclog.Infof("dialing to fallback server %s failed: %v", fallbackServerAddr, fbErr)
|
||||
return nil, nil, fmt.Errorf("dialing to fallback server %s failed: %v; S2A client handshake with %s error: %w", fallbackServerAddr, fbErr, targetServer, s2aErr)
|
||||
}
|
||||
|
||||
tc, success := fbConn.(*tls.Conn)
|
||||
if !success {
|
||||
grpclog.Infof("the connection with fallback server is expected to be tls but isn't")
|
||||
return nil, nil, fmt.Errorf("the connection with fallback server is expected to be tls but isn't; S2A client handshake with %s error: %w", targetServer, s2aErr)
|
||||
}
|
||||
|
||||
tlsInfo := credentials.TLSInfo{
|
||||
State: tc.ConnectionState(),
|
||||
CommonAuthInfo: credentials.CommonAuthInfo{
|
||||
SecurityLevel: credentials.PrivacyAndIntegrity,
|
||||
},
|
||||
}
|
||||
if grpclog.V(1) {
|
||||
grpclog.Infof("ConnectionState.NegotiatedProtocol: %v", tc.ConnectionState().NegotiatedProtocol)
|
||||
grpclog.Infof("ConnectionState.HandshakeComplete: %v", tc.ConnectionState().HandshakeComplete)
|
||||
grpclog.Infof("ConnectionState.ServerName: %v", tc.ConnectionState().ServerName)
|
||||
}
|
||||
conn.Close()
|
||||
return fbConn, tlsInfo, nil
|
||||
}, nil
|
||||
}
|
||||
|
||||
// DefaultFallbackDialerAndAddress returns a TLS dialer and the network address to dial.
|
||||
// Example use:
|
||||
//
|
||||
// fallbackDialer, fallbackServerAddr := fallback.DefaultFallbackDialerAndAddress(fallbackAddr)
|
||||
// dialTLSContext := s2a.NewS2aDialTLSContextFunc(&s2a.ClientOptions{
|
||||
// S2AAddress: s2aAddress, // required
|
||||
// FallbackOpts: &s2a.FallbackOptions{
|
||||
// FallbackDialer: &s2a.FallbackDialer{
|
||||
// Dialer: fallbackDialer,
|
||||
// ServerAddr: fallbackServerAddr,
|
||||
// },
|
||||
// },
|
||||
// })
|
||||
//
|
||||
// The fallback server's certificate should be verifiable using OS root store.
|
||||
// The fallbackAddr is expected to be a network address, e.g. example.com:port. If port is not specified,
|
||||
// it uses default port 443.
|
||||
// In the returned function's TLS config, ClientSessionCache is explicitly set to nil to disable TLS resumption,
|
||||
// and min TLS version is set to 1.3.
|
||||
func DefaultFallbackDialerAndAddress(fallbackAddr string) (*tls.Dialer, string, error) {
|
||||
fallbackServerAddr, err := processFallbackAddr(fallbackAddr)
|
||||
if err != nil {
|
||||
if grpclog.V(1) {
|
||||
grpclog.Infof("error processing fallback address [%s]: %v", fallbackAddr, err)
|
||||
}
|
||||
return nil, "", err
|
||||
}
|
||||
return &tls.Dialer{Config: &FallbackTLSConfigHTTP}, fallbackServerAddr, nil
|
||||
}
|
||||
|
||||
func processFallbackAddr(fallbackAddr string) (string, error) {
|
||||
var fallbackServerAddr string
|
||||
var err error
|
||||
|
||||
if fallbackAddr == "" {
|
||||
return "", fmt.Errorf("empty fallback address")
|
||||
}
|
||||
_, _, err = net.SplitHostPort(fallbackAddr)
|
||||
if err != nil {
|
||||
// fallbackAddr does not have port suffix
|
||||
fallbackServerAddr = net.JoinHostPort(fallbackAddr, defaultHTTPSPort)
|
||||
} else {
|
||||
// FallbackServerAddr already has port suffix
|
||||
fallbackServerAddr = fallbackAddr
|
||||
}
|
||||
return fallbackServerAddr, nil
|
||||
}
|
Reference in New Issue
Block a user