@@ -13,13 +13,17 @@ pub enum Resolver {
13
13
/// Read the list of nameservers from the system, and use that.
14
14
SystemDefault ,
15
15
16
- // Use a resolver specified by the user.
16
+ // Use a specific nameserver specified by the user.
17
17
Specified ( Nameserver ) ,
18
18
}
19
19
20
20
pub type Nameserver = String ;
21
21
22
22
impl Resolver {
23
+
24
+ /// Returns a nameserver that queries should be sent to, possibly by
25
+ /// obtaining one based on the system, returning an error if there was a
26
+ /// problem looking one up.
23
27
pub fn lookup ( self ) -> io:: Result < Option < Nameserver > > {
24
28
match self {
25
29
Self :: Specified ( ns) => Ok ( Some ( ns) ) ,
@@ -29,6 +33,10 @@ impl Resolver {
29
33
}
30
34
31
35
36
+ /// Looks up the system default nameserver on Unix, by querying
37
+ /// `/etc/resolv.conf` and returning the first line that specifies one.
38
+ /// Returns an error if there’s a problem reading the file, or `None` if no
39
+ /// nameserver is specified in the file.
32
40
#[ cfg( unix) ]
33
41
fn system_nameservers ( ) -> io:: Result < Option < Nameserver > > {
34
42
use std:: io:: { BufRead , BufReader } ;
@@ -54,7 +62,45 @@ fn system_nameservers() -> io::Result<Option<Nameserver>> {
54
62
Ok ( nameservers. first ( ) . cloned ( ) )
55
63
}
56
64
57
- #[ cfg( not( unix) ) ]
65
+
66
+ /// Looks up the system default nameserver on Windows, by iterating through
67
+ /// the list of network adapters and returning the first nameserver it finds.
68
+ #[ cfg( windows) ]
69
+ fn system_nameservers ( ) -> io:: Result < Option < Nameserver > > {
70
+ let adapters = match ipconfig:: get_adapters ( ) {
71
+ Ok ( a) => a,
72
+ Err ( e) => {
73
+ warn ! ( "Error getting network adapters: {}" , e) ;
74
+ return Ok ( None ) ;
75
+ }
76
+ } ;
77
+
78
+ let first_adapter = match adapters. first ( ) {
79
+ Some ( a) => a,
80
+ None => {
81
+ warn ! ( "No network adapters available" ) ;
82
+ return Ok ( None ) ;
83
+ }
84
+ } ;
85
+ debug ! ( "Found network adapter {:?}" , first_adapter. adapter_name( ) ) ;
86
+
87
+ let first_nameserver = match first_adapter. dns_servers ( ) . first ( ) {
88
+ Some ( ns) => ns,
89
+ None => {
90
+ warn ! ( "No nameservers available" ) ;
91
+ return Ok ( None ) ;
92
+ }
93
+ } ;
94
+ debug ! ( "Found nameserver {:?}" , first_nameserver) ;
95
+
96
+ // todo: have this not be turned into a string, then parsed again later
97
+ Ok ( Some ( first_nameserver. to_string ( ) ) )
98
+ }
99
+
100
+
101
+ /// The fall-back system default nameserver determinator that is not very
102
+ /// determined as it returns nothing without actually checking anything.
103
+ #[ cfg( all( not( unix) , not( windows) ) ) ]
58
104
fn system_nameservers ( ) -> io:: Result < Option < Nameserver > > {
59
105
warn ! ( "Unable to fetch default nameservers on this platform." ) ;
60
106
Ok ( None )
0 commit comments