internal.go

 1/*
 2 *
 3 * Copyright 2023 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 internal contains functionality internal to the dns resolver package.
20package internal
21
22import (
23	"context"
24	"errors"
25	"net"
26	"time"
27)
28
29// NetResolver groups the methods on net.Resolver that are used by the DNS
30// resolver implementation. This allows the default net.Resolver instance to be
31// overridden from tests.
32type NetResolver interface {
33	LookupHost(ctx context.Context, host string) (addrs []string, err error)
34	LookupSRV(ctx context.Context, service, proto, name string) (cname string, addrs []*net.SRV, err error)
35	LookupTXT(ctx context.Context, name string) (txts []string, err error)
36}
37
38var (
39	// ErrMissingAddr is the error returned when building a DNS resolver when
40	// the provided target name is empty.
41	ErrMissingAddr = errors.New("dns resolver: missing address")
42
43	// ErrEndsWithColon is the error returned when building a DNS resolver when
44	// the provided target name ends with a colon that is supposed to be the
45	// separator between host and port.  E.g. "::" is a valid address as it is
46	// an IPv6 address (host only) and "[::]:" is invalid as it ends with a
47	// colon as the host and port separator
48	ErrEndsWithColon = errors.New("dns resolver: missing port after port-separator colon")
49)
50
51// The following vars are overridden from tests.
52var (
53	// TimeAfterFunc is used by the DNS resolver to wait for the given duration
54	// to elapse. In non-test code, this is implemented by time.After. In test
55	// code, this can be used to control the amount of time the resolver is
56	// blocked waiting for the duration to elapse.
57	TimeAfterFunc func(time.Duration) <-chan time.Time
58
59	// TimeNowFunc is used by the DNS resolver to get the current time.
60	// In non-test code, this is implemented by time.Now. In test code,
61	// this can be used to control the current time for the resolver.
62	TimeNowFunc func() time.Time
63
64	// TimeUntilFunc is used by the DNS resolver to calculate the remaining
65	// wait time for re-resolution. In non-test code, this is implemented by
66	// time.Until. In test code, this can be used to control the remaining
67	// time for resolver to wait for re-resolution.
68	TimeUntilFunc func(time.Time) time.Duration
69
70	// NewNetResolver returns the net.Resolver instance for the given target.
71	NewNetResolver func(string) (NetResolver, error)
72
73	// AddressDialer is the dialer used to dial the DNS server. It accepts the
74	// Host portion of the URL corresponding to the user's dial target and
75	// returns a dial function.
76	AddressDialer func(address string) func(context.Context, string, string) (net.Conn, error)
77)