@@ -3,7 +3,8 @@ use crate::network::dns::dns_table::DnsTable;
3
3
use crate :: network:: dns:: hosts:: HostsResolver ;
4
4
use crate :: network:: dns:: ns_policy:: { DispatchedDnsResolver , NameserverPolicies } ;
5
5
use crate :: network:: dns:: provider:: IfaceProvider ;
6
- use crate :: proxy:: error:: TransportError ;
6
+ use crate :: network:: dns:: { default_resolver_opt, AuxiliaryResolver , NameServerConfigEnum } ;
7
+ use crate :: proxy:: error:: { DnsError , TransportError } ;
7
8
use arc_swap:: ArcSwap ;
8
9
use hickory_proto:: op:: { Message , MessageType , ResponseCode } ;
9
10
use hickory_proto:: rr:: { DNSClass , RData , Record , RecordType } ;
@@ -52,13 +53,40 @@ macro_rules! impl_genuine_lookup {
52
53
} ;
53
54
}
54
55
56
+ macro_rules! apply_resolver {
57
+ ( $func_name: ident, $name: expr, $domain_name: expr, $auxiliary_resolver: expr) => {
58
+ match $auxiliary_resolver {
59
+ AuxiliaryResolver :: Dhcp ( inner) => {
60
+ let resolver = {
61
+ let mut guard = inner. lock( ) . unwrap( ) ;
62
+ match guard. refresh( ) {
63
+ Ok ( _) => { }
64
+ Err ( e) => {
65
+ tracing:: warn!(
66
+ "failed to update DHCP DNS at ({},{},{}): {:?}" ,
67
+ guard. iface,
68
+ guard. iface_addr,
69
+ guard. ns_addr,
70
+ e
71
+ ) ;
72
+ }
73
+ }
74
+ guard. get_resolver( )
75
+ } ;
76
+ $func_name( $name, $domain_name, & resolver) . await
77
+ }
78
+ AuxiliaryResolver :: Resolver ( inner) => $func_name( $name, $domain_name, & inner) . await ,
79
+ }
80
+ } ;
81
+ }
82
+
55
83
pub struct GenericDns < P : RuntimeProvider > {
56
84
name : String ,
57
85
table : DnsTable ,
58
86
preference : DnsPreference ,
59
87
host_resolver : ArcSwap < HostsResolver > ,
60
88
ns_policy : ArcSwap < NameserverPolicies > ,
61
- resolvers : ArcSwap < Vec < AsyncResolver < GenericConnector < P > > > > ,
89
+ resolvers : ArcSwap < Vec < AuxiliaryResolver < AsyncResolver < GenericConnector < P > > > > > ,
62
90
}
63
91
64
92
pub type Dns = GenericDns < IfaceProvider > ;
@@ -70,28 +98,18 @@ impl Dns {
70
98
preference : DnsPreference ,
71
99
hosts : & HashMap < String , IpAddr > ,
72
100
ns_policy : NameserverPolicies ,
73
- configs : Vec < NameServerConfigGroup > ,
74
- ) -> Dns {
75
- let resolvers = configs
76
- . into_iter ( )
77
- . map ( |config| {
78
- let cfg = ResolverConfig :: from_parts ( None , vec ! [ ] , config) ;
79
- AsyncResolver :: new (
80
- cfg,
81
- Self :: default_resolver_opt ( ) ,
82
- GenericConnector :: new ( IfaceProvider :: new ( iface_name) ) ,
83
- )
84
- } )
85
- . collect ( ) ;
101
+ configs : Vec < NameServerConfigEnum > ,
102
+ ) -> Result < Dns , DnsError > {
103
+ let resolvers = Self :: build_resolvers ( iface_name, configs) ?;
86
104
let host_resolver = HostsResolver :: new ( hosts) ;
87
- Dns {
105
+ Ok ( Dns {
88
106
name : name. to_string ( ) ,
89
107
table : DnsTable :: new ( ) ,
90
108
preference,
91
109
host_resolver : ArcSwap :: new ( Arc :: new ( host_resolver) ) ,
92
110
ns_policy : ArcSwap :: new ( Arc :: new ( ns_policy) ) ,
93
111
resolvers : ArcSwap :: new ( Arc :: new ( resolvers) ) ,
94
- }
112
+ } )
95
113
}
96
114
97
115
pub fn replace_hosts ( & self , hosts : & HashMap < String , IpAddr > ) {
@@ -103,26 +121,38 @@ impl Dns {
103
121
self . ns_policy . store ( Arc :: new ( ns_policy) ) ;
104
122
}
105
123
106
- pub fn replace_resolvers ( & self , iface_name : & str , configs : Vec < NameServerConfigGroup > ) {
107
- let resolvers = configs
108
- . into_iter ( )
109
- . map ( |config| {
110
- let cfg = ResolverConfig :: from_parts ( None , vec ! [ ] , config) ;
111
- AsyncResolver :: new (
112
- cfg,
113
- Self :: default_resolver_opt ( ) ,
114
- GenericConnector :: new ( IfaceProvider :: new ( iface_name) ) ,
115
- )
116
- } )
117
- . collect ( ) ;
124
+ // This function is atomic
125
+ pub fn replace_resolvers (
126
+ & self ,
127
+ iface_name : & str ,
128
+ configs : Vec < NameServerConfigEnum > ,
129
+ ) -> Result < ( ) , DnsError > {
130
+ let resolvers = Self :: build_resolvers ( iface_name, configs) ?;
118
131
self . resolvers . store ( Arc :: new ( resolvers) ) ;
132
+ Ok ( ( ) )
119
133
}
120
134
121
- fn default_resolver_opt ( ) -> ResolverOpts {
122
- let mut opts = ResolverOpts :: default ( ) ;
123
- opts. timeout = Duration :: from_millis ( 1600 ) ;
124
- opts. attempts = 3 ;
125
- opts
135
+ fn build_resolvers (
136
+ iface_name : & str ,
137
+ configs : Vec < NameServerConfigEnum > ,
138
+ ) -> Result < Vec < AuxiliaryResolver < AsyncResolver < GenericConnector < IfaceProvider > > > > , DnsError >
139
+ {
140
+ let mut resolvers = Vec :: new ( ) ;
141
+ for config in configs. into_iter ( ) {
142
+ let resolver = match config {
143
+ NameServerConfigEnum :: Normal ( config) => {
144
+ let cfg = ResolverConfig :: from_parts ( None , vec ! [ ] , config) ;
145
+ AuxiliaryResolver :: new_normal ( AsyncResolver :: new (
146
+ cfg,
147
+ default_resolver_opt ( ) ,
148
+ GenericConnector :: new ( IfaceProvider :: new ( iface_name) ) ,
149
+ ) )
150
+ }
151
+ NameServerConfigEnum :: Dhcp ( dhcp) => AuxiliaryResolver :: new_dhcp ( & dhcp) ?,
152
+ } ;
153
+ resolvers. push ( resolver) ;
154
+ }
155
+ Ok ( resolvers)
126
156
}
127
157
}
128
158
@@ -138,7 +168,7 @@ impl<P: RuntimeProvider> GenericDns<P> {
138
168
preference,
139
169
host_resolver : ArcSwap :: new ( Arc :: new ( HostsResolver :: empty ( ) ) ) ,
140
170
ns_policy : ArcSwap :: new ( Arc :: new ( NameserverPolicies :: empty ( ) ) ) ,
141
- resolvers : ArcSwap :: new ( Arc :: new ( vec ! [ resolver] ) ) ,
171
+ resolvers : ArcSwap :: new ( Arc :: new ( vec ! [ AuxiliaryResolver :: new_normal ( resolver) ] ) ) ,
142
172
}
143
173
}
144
174
@@ -161,35 +191,32 @@ impl<P: RuntimeProvider> GenericDns<P> {
161
191
162
192
async fn genuine_lookup_v4 ( & self , domain_name : & str ) -> Result < Option < IpAddr > , TransportError > {
163
193
for r in self . resolvers . load ( ) . iter ( ) {
164
- if let Some ( ip) = Self :: genuine_lookup_one_v4 ( & self . name , domain_name, r) . await ? {
194
+ if let Some ( ip) = apply_resolver ! ( genuine_lookup_one_v4 , & self . name, domain_name, r) ? {
165
195
return Ok ( Some ( ip) ) ;
166
196
}
167
197
}
168
198
Ok ( None )
169
199
}
170
200
async fn genuine_lookup_v6 ( & self , domain_name : & str ) -> Result < Option < IpAddr > , TransportError > {
171
201
for r in self . resolvers . load ( ) . iter ( ) {
172
- if let Some ( ip) = Self :: genuine_lookup_one_v6 ( & self . name , domain_name, r) . await ? {
202
+ if let Some ( ip) = apply_resolver ! ( genuine_lookup_one_v6 , & self . name, domain_name, r) ? {
173
203
return Ok ( Some ( ip) ) ;
174
204
}
175
205
}
176
206
Ok ( None )
177
207
}
178
208
179
- impl_genuine_lookup ! ( genuine_lookup_one_v4, ipv4_lookup) ;
180
- impl_genuine_lookup ! ( genuine_lookup_one_v6, ipv6_lookup) ;
181
-
182
209
async fn one_v4_wrapper (
183
210
name : & str ,
184
211
domain_name : & str ,
185
212
resolver : & DispatchedDnsResolver ,
186
213
) -> Result < Option < IpAddr > , TransportError > {
187
214
match resolver {
188
215
DispatchedDnsResolver :: Iface ( resolver) => {
189
- Self :: genuine_lookup_one_v4 ( name, domain_name, resolver) . await
216
+ apply_resolver ! ( genuine_lookup_one_v4 , name, domain_name, resolver)
190
217
}
191
218
DispatchedDnsResolver :: Plain ( resolver) => {
192
- Self :: genuine_lookup_one_v4 ( name, domain_name, resolver) . await
219
+ genuine_lookup_one_v4 ( name, domain_name, resolver) . await
193
220
}
194
221
}
195
222
}
@@ -201,10 +228,10 @@ impl<P: RuntimeProvider> GenericDns<P> {
201
228
) -> Result < Option < IpAddr > , TransportError > {
202
229
match resolver {
203
230
DispatchedDnsResolver :: Iface ( resolver) => {
204
- Self :: genuine_lookup_one_v6 ( name, domain_name, resolver) . await
231
+ apply_resolver ! ( genuine_lookup_one_v6 , name, domain_name, resolver)
205
232
}
206
233
DispatchedDnsResolver :: Plain ( resolver) => {
207
- Self :: genuine_lookup_one_v6 ( name, domain_name, resolver) . await
234
+ genuine_lookup_one_v6 ( name, domain_name, resolver) . await
208
235
}
209
236
}
210
237
}
@@ -331,3 +358,6 @@ impl<P: RuntimeProvider> GenericDns<P> {
331
358
}
332
359
}
333
360
}
361
+
362
+ impl_genuine_lookup ! ( genuine_lookup_one_v4, ipv4_lookup) ;
363
+ impl_genuine_lookup ! ( genuine_lookup_one_v6, ipv6_lookup) ;
0 commit comments