@@ -2,6 +2,7 @@ package doh
2
2
3
3
import (
4
4
"context"
5
+ "math"
5
6
"net"
6
7
"strings"
7
8
"sync"
@@ -17,8 +18,9 @@ type Resolver struct {
17
18
url string
18
19
19
20
// RR cache
20
- ipCache map [string ]ipAddrEntry
21
- txtCache map [string ]txtEntry
21
+ ipCache map [string ]ipAddrEntry
22
+ txtCache map [string ]txtEntry
23
+ maxCacheTTL time.Duration
22
24
}
23
25
24
26
type ipAddrEntry struct {
@@ -31,16 +33,43 @@ type txtEntry struct {
31
33
expire time.Time
32
34
}
33
35
34
- func NewResolver (url string ) * Resolver {
36
+ type Option func (* Resolver ) error
37
+
38
+ // Specifies the maximum time entries are valid in the cache
39
+ // A maxCacheTTL of zero is equivalent to `WithCacheDisabled`
40
+ func WithMaxCacheTTL (maxCacheTTL time.Duration ) Option {
41
+ return func (tr * Resolver ) error {
42
+ tr .maxCacheTTL = maxCacheTTL
43
+ return nil
44
+ }
45
+ }
46
+
47
+ func WithCacheDisabled () Option {
48
+ return func (tr * Resolver ) error {
49
+ tr .maxCacheTTL = 0
50
+ return nil
51
+ }
52
+ }
53
+
54
+ func NewResolver (url string , opts ... Option ) (* Resolver , error ) {
35
55
if ! strings .HasPrefix (url , "https:" ) {
36
56
url = "https://" + url
37
57
}
38
58
39
- return & Resolver {
40
- url : url ,
41
- ipCache : make (map [string ]ipAddrEntry ),
42
- txtCache : make (map [string ]txtEntry ),
59
+ r := & Resolver {
60
+ url : url ,
61
+ ipCache : make (map [string ]ipAddrEntry ),
62
+ txtCache : make (map [string ]txtEntry ),
63
+ maxCacheTTL : time .Duration (math .MaxUint32 ) * time .Second ,
43
64
}
65
+
66
+ for _ , o := range opts {
67
+ if err := o (r ); err != nil {
68
+ return nil , err
69
+ }
70
+ }
71
+
72
+ return r , nil
44
73
}
45
74
46
75
var _ madns.BasicResolver = (* Resolver )(nil )
@@ -81,7 +110,8 @@ func (r *Resolver) LookupIPAddr(ctx context.Context, domain string) (result []ne
81
110
}
82
111
}
83
112
84
- r .cacheIPAddr (domain , result , ttl )
113
+ cacheTTL := minTTL (time .Duration (ttl )* time .Second , r .maxCacheTTL )
114
+ r .cacheIPAddr (domain , result , cacheTTL )
85
115
return result , nil
86
116
}
87
117
@@ -96,7 +126,8 @@ func (r *Resolver) LookupTXT(ctx context.Context, domain string) ([]string, erro
96
126
return nil , err
97
127
}
98
128
99
- r .cacheTXT (domain , result , ttl )
129
+ cacheTTL := minTTL (time .Duration (ttl )* time .Second , r .maxCacheTTL )
130
+ r .cacheTXT (domain , result , cacheTTL )
100
131
return result , nil
101
132
}
102
133
@@ -118,7 +149,7 @@ func (r *Resolver) getCachedIPAddr(domain string) ([]net.IPAddr, bool) {
118
149
return entry .ips , true
119
150
}
120
151
121
- func (r * Resolver ) cacheIPAddr (domain string , ips []net.IPAddr , ttl uint32 ) {
152
+ func (r * Resolver ) cacheIPAddr (domain string , ips []net.IPAddr , ttl time. Duration ) {
122
153
if ttl == 0 {
123
154
return
124
155
}
@@ -127,7 +158,7 @@ func (r *Resolver) cacheIPAddr(domain string, ips []net.IPAddr, ttl uint32) {
127
158
defer r .mx .Unlock ()
128
159
129
160
fqdn := dns .Fqdn (domain )
130
- r .ipCache [fqdn ] = ipAddrEntry {ips , time .Now ().Add (time . Duration ( ttl ) * time . Second )}
161
+ r .ipCache [fqdn ] = ipAddrEntry {ips , time .Now ().Add (ttl )}
131
162
}
132
163
133
164
func (r * Resolver ) getCachedTXT (domain string ) ([]string , bool ) {
@@ -148,7 +179,7 @@ func (r *Resolver) getCachedTXT(domain string) ([]string, bool) {
148
179
return entry .txt , true
149
180
}
150
181
151
- func (r * Resolver ) cacheTXT (domain string , txt []string , ttl uint32 ) {
182
+ func (r * Resolver ) cacheTXT (domain string , txt []string , ttl time. Duration ) {
152
183
if ttl == 0 {
153
184
return
154
185
}
@@ -157,5 +188,12 @@ func (r *Resolver) cacheTXT(domain string, txt []string, ttl uint32) {
157
188
defer r .mx .Unlock ()
158
189
159
190
fqdn := dns .Fqdn (domain )
160
- r .txtCache [fqdn ] = txtEntry {txt , time .Now ().Add (time .Duration (ttl ) * time .Second )}
191
+ r .txtCache [fqdn ] = txtEntry {txt , time .Now ().Add (ttl )}
192
+ }
193
+
194
+ func minTTL (a , b time.Duration ) time.Duration {
195
+ if a < b {
196
+ return a
197
+ }
198
+ return b
161
199
}
0 commit comments