@@ -37,6 +37,8 @@ def self.ipv6?
37
37
list . any? { |a | a . ipv6? && !a . ipv6_loopback? && !a . ipv6_linklocal? }
38
38
end
39
39
40
+ Resource = Struct . new ( :address , :ttl )
41
+
40
42
# An interface for querying the system's hosts file.
41
43
class Hosts
42
44
# Hosts for the local system.
@@ -84,17 +86,31 @@ def add(address, names)
84
86
@addresses [ address ] += names
85
87
86
88
names . each do |name |
89
+ name = Resolv ::DNS ::Name . create ( name ) . with_origin ( nil )
90
+
87
91
@names [ name ] ||= [ ]
88
92
@names [ name ] << address
89
93
end
90
94
end
91
95
96
+ def each ( &block )
97
+ @names . each ( &block )
98
+ end
99
+
92
100
# Parse a hosts file and add the entries.
93
101
def parse_hosts ( io )
94
102
io . each do |line |
95
103
line . sub! ( /#.*/ , '' )
96
104
address , hostname , *aliases = line . split ( /\s +/ )
97
105
106
+ if address =~ Resolv ::IPv4 ::Regex
107
+ address = Resolv ::IPv4 . create ( address )
108
+ elsif address =~ Resolv ::IPv6 ::Regex
109
+ address = Resolv ::IPv6 . create ( address )
110
+ else
111
+ next
112
+ end
113
+
98
114
add ( address , [ hostname ] + aliases )
99
115
end
100
116
end
@@ -169,6 +185,24 @@ def self.resolver(**options)
169
185
options [ :search ] = [ nil ]
170
186
end
171
187
188
+ if hosts = Hosts . local
189
+ cache = options . fetch ( :cache ) do
190
+ options [ :cache ] = Cache . new
191
+ end
192
+
193
+ hosts . each do |name , addresses |
194
+ addresses . each do |address |
195
+ resource = Resource . new ( address , nil )
196
+ case address
197
+ when Resolv ::IPv4
198
+ cache . store ( name , Resolv ::DNS ::Resource ::IN ::A , resource )
199
+ when Resolv ::IPv6
200
+ cache . store ( name , Resolv ::DNS ::Resource ::IN ::AAAA , resource )
201
+ end
202
+ end
203
+ end
204
+ end
205
+
172
206
timeout = options . delete ( :timeout ) || DEFAULT_TIMEOUT
173
207
endpoint = Endpoint . for ( nameservers , timeout : timeout )
174
208
0 commit comments