@@ -4,41 +4,45 @@ use crate::config;
4
4
use core:: fmt;
5
5
use hickory_resolver:: { config:: * , error:: ResolveError , TokioAsyncResolver } ;
6
6
use rustls:: ClientConfig ;
7
- use std:: { net:: IpAddr , sync:: Arc } ;
7
+ use std:: { net:: IpAddr , sync:: Arc , time:: Duration } ;
8
+ use tokio:: time:: error:: Elapsed ;
8
9
9
10
/// The port to connect to the DoH resolvers over.
10
11
const RESOLVER_PORT : u16 = 443 ;
12
+ const DEFAULT_TIMEOUT : Duration = std:: time:: Duration :: from_secs ( 10 ) ;
11
13
12
14
pub struct Nameserver {
13
15
pub name : String ,
14
16
pub addr : Vec < IpAddr > ,
15
17
}
16
18
17
19
#[ derive( Debug ) ]
18
- pub struct ResolutionError ( ResolveError ) ;
20
+ pub enum Error {
21
+ ResolutionError ( ResolveError ) ,
22
+ Timeout ( Elapsed ) ,
23
+ }
19
24
20
- impl fmt:: Display for ResolutionError {
25
+ impl fmt:: Display for Error {
21
26
fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
22
- self . 0 . fmt ( f)
27
+ match self {
28
+ Error :: ResolutionError ( err) => err. fmt ( f) ,
29
+ Error :: Timeout ( err) => err. fmt ( f) ,
30
+ }
23
31
}
24
32
}
25
33
26
- impl std:: error:: Error for ResolutionError {
34
+ impl std:: error:: Error for Error {
27
35
fn source ( & self ) -> Option < & ( dyn std:: error:: Error + ' static ) > {
28
- self . 0 . source ( )
36
+ match self {
37
+ Self :: ResolutionError ( ref err) => Some ( err) ,
38
+ Self :: Timeout ( ref err) => Some ( err) ,
39
+ }
29
40
}
30
41
}
31
42
32
43
/// Returns a set of well known public DoH resolvers. A sane default in many cases.
33
44
pub fn default_resolvers ( ) -> Vec < Nameserver > {
34
45
vec ! [
35
- Nameserver {
36
- name: "dns.quad9.net" . to_owned( ) ,
37
- addr: vec![
38
- "9.9.9.9" . parse( ) . unwrap( ) ,
39
- "149.112.112.112" . parse( ) . unwrap( ) ,
40
- ] ,
41
- } ,
42
46
Nameserver {
43
47
name: "one.one.one.one" . to_owned( ) ,
44
48
addr: vec![ "1.1.1.1" . parse( ) . unwrap( ) , "1.0.0.1" . parse( ) . unwrap( ) ] ,
@@ -47,6 +51,13 @@ pub fn default_resolvers() -> Vec<Nameserver> {
47
51
name: "dns.google" . to_owned( ) ,
48
52
addr: vec![ "8.8.8.8" . parse( ) . unwrap( ) , "8.8.4.4" . parse( ) . unwrap( ) ] ,
49
53
} ,
54
+ Nameserver {
55
+ name: "dns.quad9.net" . to_owned( ) ,
56
+ addr: vec![
57
+ "9.9.9.9" . parse( ) . unwrap( ) ,
58
+ "149.112.112.112" . parse( ) . unwrap( ) ,
59
+ ] ,
60
+ } ,
50
61
]
51
62
}
52
63
@@ -55,8 +66,8 @@ pub fn default_resolvers() -> Vec<Nameserver> {
55
66
pub async fn resolve_configs (
56
67
resolvers : & [ Nameserver ] ,
57
68
domain : & str ,
58
- ) -> Result < Vec < config:: ProxyConfig > , ResolutionError > {
59
- let mut resolver_config = ResolverConfig :: new ( ) ;
69
+ ) -> Result < Vec < config:: ProxyConfig > , Error > {
70
+ let mut nameservers = ResolverConfig :: new ( ) ;
60
71
for resolver in resolvers. iter ( ) {
61
72
let ns_config_group = NameServerConfigGroup :: from_ips_https (
62
73
& resolver. addr ,
@@ -66,25 +77,28 @@ pub async fn resolve_configs(
66
77
)
67
78
. into_inner ( ) ;
68
79
for ns_config in ns_config_group {
69
- resolver_config . add_name_server ( ns_config) ;
80
+ nameservers . add_name_server ( ns_config) ;
70
81
}
71
82
}
72
83
73
- resolver_config. set_tls_client_config ( Arc :: new ( client_config_tls12 ( ) ) ) ;
84
+ nameservers. set_tls_client_config ( Arc :: new ( client_config_tls12 ( ) ) ) ;
85
+ let mut resolver_config: ResolverOpts = Default :: default ( ) ;
74
86
75
- resolve_config_with_resolverconfig ( resolver_config, Default :: default ( ) , domain) . await
87
+ resolver_config. timeout = Duration :: from_secs ( 5 ) ;
88
+ resolve_config_with_resolverconfig ( nameservers, resolver_config, domain, DEFAULT_TIMEOUT ) . await
76
89
}
77
90
78
91
pub async fn resolve_config_with_resolverconfig (
79
92
resolver_config : ResolverConfig ,
80
93
options : ResolverOpts ,
81
94
domain : & str ,
82
- ) -> Result < Vec < config:: ProxyConfig > , ResolutionError > {
95
+ timeout : Duration ,
96
+ ) -> Result < Vec < config:: ProxyConfig > , Error > {
83
97
let resolver = TokioAsyncResolver :: tokio ( resolver_config, options) ;
84
- let lookup = resolver
85
- . ipv6_lookup ( domain)
98
+ let lookup = tokio:: time:: timeout ( timeout, resolver. ipv6_lookup ( domain) )
86
99
. await
87
- . map_err ( ResolutionError ) ?;
100
+ . map_err ( Error :: Timeout ) ?
101
+ . map_err ( Error :: ResolutionError ) ?;
88
102
89
103
let addrs = lookup. into_iter ( ) . map ( |aaaa_record| aaaa_record. 0 ) ;
90
104
@@ -102,11 +116,6 @@ pub async fn resolve_config_with_resolverconfig(
102
116
Ok ( proxy_configs)
103
117
}
104
118
105
- pub async fn resolve_default_config ( ) -> Result < Vec < config:: ProxyConfig > , ResolutionError > {
106
- resolve_configs ( & default_resolvers ( ) , "frakta.eu" ) . await
107
-
108
- }
109
-
110
119
fn client_config_tls12 ( ) -> ClientConfig {
111
120
use rustls:: RootCertStore ;
112
121
let mut root_store = RootCertStore :: empty ( ) ;
0 commit comments