resolver.go raw

   1  /*
   2   *
   3   * Copyright 2017 gRPC authors.
   4   *
   5   * Licensed under the Apache License, Version 2.0 (the "License");
   6   * you may not use this file except in compliance with the License.
   7   * You may obtain a copy of the License at
   8   *
   9   *     http://www.apache.org/licenses/LICENSE-2.0
  10   *
  11   * Unless required by applicable law or agreed to in writing, software
  12   * distributed under the License is distributed on an "AS IS" BASIS,
  13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14   * See the License for the specific language governing permissions and
  15   * limitations under the License.
  16   *
  17   */
  18  
  19  // Package resolver defines APIs for name resolution in gRPC.
  20  // All APIs in this package are experimental.
  21  package resolver
  22  
  23  import (
  24  	"context"
  25  	"errors"
  26  	"fmt"
  27  	"net"
  28  	"net/url"
  29  	"strings"
  30  
  31  	"google.golang.org/grpc/attributes"
  32  	"google.golang.org/grpc/credentials"
  33  	"google.golang.org/grpc/experimental/stats"
  34  	"google.golang.org/grpc/internal"
  35  	"google.golang.org/grpc/serviceconfig"
  36  )
  37  
  38  var (
  39  	// m is a map from scheme to resolver builder.
  40  	m = make(map[string]Builder)
  41  	// defaultScheme is the default scheme to use.
  42  	defaultScheme = "passthrough"
  43  )
  44  
  45  // TODO(bar) install dns resolver in init(){}.
  46  
  47  // Register registers the resolver builder to the resolver map. b.Scheme will
  48  // be used as the scheme registered with this builder. The registry is case
  49  // sensitive, and schemes should not contain any uppercase characters.
  50  //
  51  // NOTE: this function must only be called during initialization time (i.e. in
  52  // an init() function), and is not thread-safe. If multiple Resolvers are
  53  // registered with the same name, the one registered last will take effect.
  54  func Register(b Builder) {
  55  	m[b.Scheme()] = b
  56  }
  57  
  58  // Get returns the resolver builder registered with the given scheme.
  59  //
  60  // If no builder is register with the scheme, nil will be returned.
  61  func Get(scheme string) Builder {
  62  	if b, ok := m[scheme]; ok {
  63  		return b
  64  	}
  65  	return nil
  66  }
  67  
  68  // SetDefaultScheme sets the default scheme that will be used. The default
  69  // scheme is initially set to "passthrough".
  70  //
  71  // NOTE: this function must only be called during initialization time (i.e. in
  72  // an init() function), and is not thread-safe. The scheme set last overrides
  73  // previously set values.
  74  func SetDefaultScheme(scheme string) {
  75  	defaultScheme = scheme
  76  	internal.UserSetDefaultScheme = true
  77  }
  78  
  79  // GetDefaultScheme gets the default scheme that will be used by grpc.Dial.  If
  80  // SetDefaultScheme is never called, the default scheme used by grpc.NewClient is "dns" instead.
  81  func GetDefaultScheme() string {
  82  	return defaultScheme
  83  }
  84  
  85  // Address represents a server the client connects to.
  86  //
  87  // # Experimental
  88  //
  89  // Notice: This type is EXPERIMENTAL and may be changed or removed in a
  90  // later release.
  91  type Address struct {
  92  	// Addr is the server address on which a connection will be established.
  93  	Addr string
  94  
  95  	// ServerName is the name of this address.
  96  	// If non-empty, the ServerName is used as the transport certification authority for
  97  	// the address, instead of the hostname from the Dial target string. In most cases,
  98  	// this should not be set.
  99  	//
 100  	// WARNING: ServerName must only be populated with trusted values. It
 101  	// is insecure to populate it with data from untrusted inputs since untrusted
 102  	// values could be used to bypass the authority checks performed by TLS.
 103  	ServerName string
 104  
 105  	// Attributes contains arbitrary data about this address intended for
 106  	// consumption by the SubConn.
 107  	Attributes *attributes.Attributes
 108  
 109  	// BalancerAttributes contains arbitrary data about this address intended
 110  	// for consumption by the LB policy.  These attributes do not affect SubConn
 111  	// creation, connection establishment, handshaking, etc.
 112  	//
 113  	// Deprecated: when an Address is inside an Endpoint, this field should not
 114  	// be used, and it will eventually be removed entirely.
 115  	BalancerAttributes *attributes.Attributes
 116  
 117  	// Metadata is the information associated with Addr, which may be used
 118  	// to make load balancing decision.
 119  	//
 120  	// Deprecated: use Attributes instead.
 121  	Metadata any
 122  }
 123  
 124  // Equal returns whether a and o are identical.  Metadata is compared directly,
 125  // not with any recursive introspection.
 126  //
 127  // This method compares all fields of the address. When used to tell apart
 128  // addresses during subchannel creation or connection establishment, it might be
 129  // more appropriate for the caller to implement custom equality logic.
 130  func (a Address) Equal(o Address) bool {
 131  	return a.Addr == o.Addr && a.ServerName == o.ServerName &&
 132  		a.Attributes.Equal(o.Attributes) &&
 133  		a.BalancerAttributes.Equal(o.BalancerAttributes) &&
 134  		a.Metadata == o.Metadata
 135  }
 136  
 137  // String returns JSON formatted string representation of the address.
 138  func (a Address) String() string {
 139  	var sb strings.Builder
 140  	sb.WriteString(fmt.Sprintf("{Addr: %q, ", a.Addr))
 141  	sb.WriteString(fmt.Sprintf("ServerName: %q, ", a.ServerName))
 142  	if a.Attributes != nil {
 143  		sb.WriteString(fmt.Sprintf("Attributes: %v, ", a.Attributes.String()))
 144  	}
 145  	if a.BalancerAttributes != nil {
 146  		sb.WriteString(fmt.Sprintf("BalancerAttributes: %v", a.BalancerAttributes.String()))
 147  	}
 148  	sb.WriteString("}")
 149  	return sb.String()
 150  }
 151  
 152  // BuildOptions includes additional information for the builder to create
 153  // the resolver.
 154  type BuildOptions struct {
 155  	// DisableServiceConfig indicates whether a resolver implementation should
 156  	// fetch service config data.
 157  	DisableServiceConfig bool
 158  	// DialCreds is the transport credentials used by the ClientConn for
 159  	// communicating with the target gRPC service (set via
 160  	// WithTransportCredentials). In cases where a name resolution service
 161  	// requires the same credentials, the resolver may use this field. In most
 162  	// cases though, it is not appropriate, and this field may be ignored.
 163  	DialCreds credentials.TransportCredentials
 164  	// CredsBundle is the credentials bundle used by the ClientConn for
 165  	// communicating with the target gRPC service (set via
 166  	// WithCredentialsBundle). In cases where a name resolution service
 167  	// requires the same credentials, the resolver may use this field. In most
 168  	// cases though, it is not appropriate, and this field may be ignored.
 169  	CredsBundle credentials.Bundle
 170  	// Dialer is the custom dialer used by the ClientConn for dialling the
 171  	// target gRPC service (set via WithDialer). In cases where a name
 172  	// resolution service requires the same dialer, the resolver may use this
 173  	// field. In most cases though, it is not appropriate, and this field may
 174  	// be ignored.
 175  	Dialer func(context.Context, string) (net.Conn, error)
 176  	// Authority is the effective authority of the clientconn for which the
 177  	// resolver is built.
 178  	Authority string
 179  	// MetricsRecorder is the metrics recorder to do recording.
 180  	MetricsRecorder stats.MetricsRecorder
 181  }
 182  
 183  // An Endpoint is one network endpoint, or server, which may have multiple
 184  // addresses with which it can be accessed.
 185  type Endpoint struct {
 186  	// Addresses contains a list of addresses used to access this endpoint.
 187  	Addresses []Address
 188  
 189  	// Attributes contains arbitrary data about this endpoint intended for
 190  	// consumption by the LB policy.
 191  	Attributes *attributes.Attributes
 192  }
 193  
 194  // State contains the current Resolver state relevant to the ClientConn.
 195  type State struct {
 196  	// Addresses is the latest set of resolved addresses for the target.
 197  	//
 198  	// If a resolver sets Addresses but does not set Endpoints, one Endpoint
 199  	// will be created for each Address before the State is passed to the LB
 200  	// policy.  The BalancerAttributes of each entry in Addresses will be set
 201  	// in Endpoints.Attributes, and be cleared in the Endpoint's Address's
 202  	// BalancerAttributes.
 203  	//
 204  	// Soon, Addresses will be deprecated and replaced fully by Endpoints.
 205  	Addresses []Address
 206  
 207  	// Endpoints is the latest set of resolved endpoints for the target.
 208  	//
 209  	// If a resolver produces a State containing Endpoints but not Addresses,
 210  	// it must take care to ensure the LB policies it selects will support
 211  	// Endpoints.
 212  	Endpoints []Endpoint
 213  
 214  	// ServiceConfig contains the result from parsing the latest service
 215  	// config.  If it is nil, it indicates no service config is present or the
 216  	// resolver does not provide service configs.
 217  	ServiceConfig *serviceconfig.ParseResult
 218  
 219  	// Attributes contains arbitrary data about the resolver intended for
 220  	// consumption by the load balancing policy.
 221  	Attributes *attributes.Attributes
 222  }
 223  
 224  // ClientConn contains the callbacks for resolver to notify any updates
 225  // to the gRPC ClientConn.
 226  //
 227  // This interface is to be implemented by gRPC. Users should not need a
 228  // brand new implementation of this interface. For the situations like
 229  // testing, the new implementation should embed this interface. This allows
 230  // gRPC to add new methods to this interface.
 231  type ClientConn interface {
 232  	// UpdateState updates the state of the ClientConn appropriately.
 233  	//
 234  	// If an error is returned, the resolver should try to resolve the
 235  	// target again. The resolver should use a backoff timer to prevent
 236  	// overloading the server with requests. If a resolver is certain that
 237  	// reresolving will not change the result, e.g. because it is
 238  	// a watch-based resolver, returned errors can be ignored.
 239  	//
 240  	// If the resolved State is the same as the last reported one, calling
 241  	// UpdateState can be omitted.
 242  	UpdateState(State) error
 243  	// ReportError notifies the ClientConn that the Resolver encountered an
 244  	// error. The ClientConn then forwards this error to the load balancing
 245  	// policy.
 246  	ReportError(error)
 247  	// NewAddress is called by resolver to notify ClientConn a new list
 248  	// of resolved addresses.
 249  	// The address list should be the complete list of resolved addresses.
 250  	//
 251  	// Deprecated: Use UpdateState instead.
 252  	NewAddress(addresses []Address)
 253  	// ParseServiceConfig parses the provided service config and returns an
 254  	// object that provides the parsed config.
 255  	ParseServiceConfig(serviceConfigJSON string) *serviceconfig.ParseResult
 256  }
 257  
 258  // Target represents a target for gRPC, as specified in:
 259  // https://github.com/grpc/grpc/blob/master/doc/naming.md.
 260  // It is parsed from the target string that gets passed into Dial or DialContext
 261  // by the user. And gRPC passes it to the resolver and the balancer.
 262  //
 263  // If the target follows the naming spec, and the parsed scheme is registered
 264  // with gRPC, we will parse the target string according to the spec. If the
 265  // target does not contain a scheme or if the parsed scheme is not registered
 266  // (i.e. no corresponding resolver available to resolve the endpoint), we will
 267  // apply the default scheme, and will attempt to reparse it.
 268  type Target struct {
 269  	// URL contains the parsed dial target with an optional default scheme added
 270  	// to it if the original dial target contained no scheme or contained an
 271  	// unregistered scheme. Any query params specified in the original dial
 272  	// target can be accessed from here.
 273  	URL url.URL
 274  }
 275  
 276  // Endpoint retrieves endpoint without leading "/" from either `URL.Path`
 277  // or `URL.Opaque`. The latter is used when the former is empty.
 278  func (t Target) Endpoint() string {
 279  	endpoint := t.URL.Path
 280  	if endpoint == "" {
 281  		endpoint = t.URL.Opaque
 282  	}
 283  	// For targets of the form "[scheme]://[authority]/endpoint, the endpoint
 284  	// value returned from url.Parse() contains a leading "/". Although this is
 285  	// in accordance with RFC 3986, we do not want to break existing resolver
 286  	// implementations which expect the endpoint without the leading "/". So, we
 287  	// end up stripping the leading "/" here. But this will result in an
 288  	// incorrect parsing for something like "unix:///path/to/socket". Since we
 289  	// own the "unix" resolver, we can workaround in the unix resolver by using
 290  	// the `URL` field.
 291  	return strings.TrimPrefix(endpoint, "/")
 292  }
 293  
 294  // String returns the canonical string representation of Target.
 295  func (t Target) String() string {
 296  	return t.URL.Scheme + "://" + t.URL.Host + "/" + t.Endpoint()
 297  }
 298  
 299  // Builder creates a resolver that will be used to watch name resolution updates.
 300  type Builder interface {
 301  	// Build creates a new resolver for the given target.
 302  	//
 303  	// gRPC dial calls Build synchronously, and fails if the returned error is
 304  	// not nil.
 305  	Build(target Target, cc ClientConn, opts BuildOptions) (Resolver, error)
 306  	// Scheme returns the scheme supported by this resolver.  Scheme is defined
 307  	// at https://github.com/grpc/grpc/blob/master/doc/naming.md.  The returned
 308  	// string should not contain uppercase characters, as they will not match
 309  	// the parsed target's scheme as defined in RFC 3986.
 310  	Scheme() string
 311  }
 312  
 313  // ResolveNowOptions includes additional information for ResolveNow.
 314  type ResolveNowOptions struct{}
 315  
 316  // Resolver watches for the updates on the specified target.
 317  // Updates include address updates and service config updates.
 318  type Resolver interface {
 319  	// ResolveNow will be called by gRPC to try to resolve the target name
 320  	// again. It's just a hint, resolver can ignore this if it's not necessary.
 321  	//
 322  	// It could be called multiple times concurrently.
 323  	ResolveNow(ResolveNowOptions)
 324  	// Close closes the resolver.
 325  	Close()
 326  }
 327  
 328  // AuthorityOverrider is implemented by Builders that wish to override the
 329  // default authority for the ClientConn.
 330  // By default, the authority used is target.Endpoint().
 331  type AuthorityOverrider interface {
 332  	// OverrideAuthority returns the authority to use for a ClientConn with the
 333  	// given target. The implementation must generate it without blocking,
 334  	// typically in line, and must keep it unchanged.
 335  	//
 336  	// The returned string must be a valid ":authority" header value, i.e. be
 337  	// encoded according to
 338  	// [RFC3986](https://datatracker.ietf.org/doc/html/rfc3986#section-3.2) as
 339  	// necessary.
 340  	OverrideAuthority(Target) string
 341  }
 342  
 343  // ValidateEndpoints validates endpoints from a petiole policy's perspective.
 344  // Petiole policies should call this before calling into their children. See
 345  // [gRPC A61](https://github.com/grpc/proposal/blob/master/A61-IPv4-IPv6-dualstack-backends.md)
 346  // for details.
 347  func ValidateEndpoints(endpoints []Endpoint) error {
 348  	if len(endpoints) == 0 {
 349  		return errors.New("endpoints list is empty")
 350  	}
 351  
 352  	for _, endpoint := range endpoints {
 353  		for range endpoint.Addresses {
 354  			return nil
 355  		}
 356  	}
 357  	return errors.New("endpoints list contains no addresses")
 358  }
 359