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)