@@ -14,117 +14,127 @@ module Async::DNS
14
14
module System
15
15
RESOLV_CONF = "/etc/resolv.conf"
16
16
HOSTS = "/etc/hosts"
17
-
17
+
18
18
def self . hosts_path
19
19
if RUBY_PLATFORM =~ /mswin32|mingw|bccwin/
20
20
Win32 ::Resolv . get_hosts_path
21
21
else
22
22
HOSTS
23
23
end
24
24
end
25
-
25
+
26
+ def self . use_ipv6?
27
+ begin
28
+ list = Socket . ip_address_list
29
+ rescue NotImplementedError
30
+ return true
31
+ end
32
+
33
+ list . any? { |a | a . ipv6? && !a . ipv6_loopback? && !a . ipv6_linklocal? }
34
+ end
35
+
26
36
# This code is very experimental
27
37
class Hosts
28
38
def initialize
29
39
@addresses = { }
30
40
@names = { }
31
41
end
32
-
42
+
33
43
attr :addresses
34
44
attr :names
35
-
45
+
36
46
# This is used to match names against the list of known hosts:
37
47
def call ( name )
38
48
@names . include? ( name )
39
49
end
40
-
50
+
41
51
def lookup ( name )
42
52
addresses = @names [ name ]
43
-
53
+
44
54
if addresses
45
55
addresses . last
46
56
else
47
57
nil
48
58
end
49
59
end
50
-
60
+
51
61
alias [] lookup
52
-
62
+
53
63
def add ( address , names )
54
64
@addresses [ address ] ||= [ ]
55
65
@addresses [ address ] += names
56
-
66
+
57
67
names . each do |name |
58
68
@names [ name ] ||= [ ]
59
69
@names [ name ] << address
60
70
end
61
71
end
62
-
72
+
63
73
def parse_hosts ( io )
64
74
io . each do |line |
65
75
line . sub! ( /#.*/ , '' )
66
76
address , hostname , *aliases = line . split ( /\s +/ )
67
-
77
+
68
78
add ( address , [ hostname ] + aliases )
69
79
end
70
80
end
71
-
81
+
72
82
def self . local
73
83
hosts = self . new
74
-
84
+
75
85
path = System ::hosts_path
76
-
86
+
77
87
if path and File . exist? ( path )
78
88
File . open ( path ) do |file |
79
89
hosts . parse_hosts ( file )
80
90
end
81
91
end
82
-
92
+
83
93
return hosts
84
94
end
85
95
end
86
-
96
+
87
97
def self . parse_resolv_configuration ( path )
88
98
nameservers = [ ]
89
99
File . open ( path ) do |file |
90
100
file . each do |line |
91
101
# Remove any comments:
92
102
line . sub! ( /[#;].*/ , '' )
93
-
103
+
94
104
# Extract resolv.conf command:
95
105
keyword , *args = line . split ( /\s +/ )
96
-
106
+
97
107
case keyword
98
108
when 'nameserver'
99
109
nameservers += args
100
110
end
101
111
end
102
112
end
103
-
113
+
104
114
return nameservers
105
115
end
106
-
116
+
107
117
def self . standard_connections ( nameservers , **options )
108
118
connections = [ ]
109
-
119
+
110
120
nameservers . each do |host |
111
121
connections << IO ::Endpoint . udp ( host , 53 , **options )
112
122
connections << IO ::Endpoint . tcp ( host , 53 , **options )
113
123
end
114
-
124
+
115
125
return IO ::Endpoint . composite ( connections )
116
126
end
117
-
127
+
118
128
# Get a list of standard nameserver connections which can be used for querying any standard servers that the system has been configured with. There is no equivalent facility to use the `hosts` file at present.
119
129
def self . nameservers ( **options )
120
130
nameservers = [ ]
121
-
131
+
122
132
if File . exist? RESOLV_CONF
123
133
nameservers = parse_resolv_configuration ( RESOLV_CONF )
124
134
elsif defined? ( Win32 ::Resolv ) and RUBY_PLATFORM =~ /mswin32|cygwin|mingw|bccwin/
125
135
search , nameservers = Win32 ::Resolv . get_resolv_info
126
136
end
127
-
137
+
128
138
return standard_connections ( nameservers , **options )
129
139
end
130
140
0 commit comments