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