async-dns 1.3.0 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/lib/async/dns/cache.rb +69 -0
- data/lib/async/dns/chunked.rb +4 -19
- data/lib/async/dns/endpoint.rb +23 -0
- data/lib/async/dns/extensions/resolv.rb +22 -82
- data/lib/async/dns/extensions/string.rb +6 -20
- data/lib/async/dns/handler.rb +72 -54
- data/lib/async/dns/resolver.rb +151 -137
- data/lib/async/dns/server.rb +62 -69
- data/lib/async/dns/system.rb +147 -80
- data/lib/async/dns/transaction.rb +30 -37
- data/lib/async/dns/transport.rb +27 -39
- data/lib/async/dns/version.rb +6 -20
- data/lib/async/dns.rb +11 -27
- data/license.md +29 -0
- data/readme.md +53 -0
- data/releases.md +21 -0
- data.tar.gz.sig +0 -0
- metadata +49 -137
- metadata.gz.sig +0 -0
- data/lib/async/dns/message.rb +0 -53
- data/lib/async/dns/replace.rb +0 -54
data/lib/async/dns/system.rb
CHANGED
@@ -1,25 +1,12 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
#
|
4
|
-
#
|
5
|
-
|
6
|
-
|
7
|
-
# copies of the Software, and to permit persons to whom the Software is
|
8
|
-
# furnished to do so, subject to the following conditions:
|
9
|
-
#
|
10
|
-
# The above copyright notice and this permission notice shall be included in
|
11
|
-
# all copies or substantial portions of the Software.
|
12
|
-
#
|
13
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
-
# THE SOFTWARE.
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2015-2024, by Samuel Williams.
|
5
|
+
|
6
|
+
require_relative "endpoint"
|
20
7
|
|
21
8
|
begin
|
22
|
-
require
|
9
|
+
require "win32/resolv"
|
23
10
|
rescue LoadError
|
24
11
|
# Ignore this - we aren't running on windows.
|
25
12
|
end
|
@@ -29,7 +16,8 @@ module Async::DNS
|
|
29
16
|
module System
|
30
17
|
RESOLV_CONF = "/etc/resolv.conf"
|
31
18
|
HOSTS = "/etc/hosts"
|
32
|
-
|
19
|
+
|
20
|
+
# Get the path to the hosts file.
|
33
21
|
def self.hosts_path
|
34
22
|
if RUBY_PLATFORM =~ /mswin32|mingw|bccwin/
|
35
23
|
Win32::Resolv.get_hosts_path
|
@@ -37,110 +25,189 @@ module Async::DNS
|
|
37
25
|
HOSTS
|
38
26
|
end
|
39
27
|
end
|
40
|
-
|
41
|
-
#
|
28
|
+
|
29
|
+
# @returns [Boolean] True if the system supports IPv6.
|
30
|
+
def self.ipv6?
|
31
|
+
begin
|
32
|
+
list = Socket.ip_address_list
|
33
|
+
rescue NotImplementedError
|
34
|
+
return true
|
35
|
+
end
|
36
|
+
|
37
|
+
list.any? {|a| a.ipv6? && !a.ipv6_loopback? && !a.ipv6_linklocal? }
|
38
|
+
end
|
39
|
+
|
40
|
+
Resource = Struct.new(:address, :ttl)
|
41
|
+
|
42
|
+
# An interface for querying the system's hosts file.
|
42
43
|
class Hosts
|
44
|
+
# Hosts for the local system.
|
45
|
+
def self.local
|
46
|
+
hosts = self.new
|
47
|
+
|
48
|
+
path = System.hosts_path
|
49
|
+
|
50
|
+
if path and File.exist?(path)
|
51
|
+
File.open(path) do |file|
|
52
|
+
hosts.parse_hosts(file)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
return hosts
|
57
|
+
end
|
58
|
+
|
59
|
+
# Create a new hosts file interface.
|
43
60
|
def initialize
|
44
61
|
@addresses = {}
|
45
62
|
@names = {}
|
46
63
|
end
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
def call(name)
|
53
|
-
@names.include?(name)
|
54
|
-
end
|
55
|
-
|
56
|
-
def lookup(name)
|
64
|
+
|
65
|
+
# Lookup a name in the hosts file.
|
66
|
+
def lookup(name, origin: nil)
|
67
|
+
name = Resolv::DNS::Name.create(name).with_origin(origin)
|
68
|
+
|
57
69
|
addresses = @names[name]
|
58
|
-
|
70
|
+
|
59
71
|
if addresses
|
60
72
|
addresses.last
|
61
73
|
else
|
62
74
|
nil
|
63
75
|
end
|
64
76
|
end
|
65
|
-
|
77
|
+
|
66
78
|
alias [] lookup
|
67
|
-
|
79
|
+
|
80
|
+
# Add a new address with the given names.
|
68
81
|
def add(address, names)
|
69
82
|
@addresses[address] ||= []
|
70
83
|
@addresses[address] += names
|
71
|
-
|
84
|
+
|
72
85
|
names.each do |name|
|
86
|
+
name = Resolv::DNS::Name.create(name).with_origin(nil)
|
87
|
+
|
73
88
|
@names[name] ||= []
|
74
89
|
@names[name] << address
|
75
90
|
end
|
76
91
|
end
|
77
|
-
|
92
|
+
|
93
|
+
def each(&block)
|
94
|
+
@names.each(&block)
|
95
|
+
end
|
96
|
+
|
97
|
+
# Parse a hosts file and add the entries.
|
78
98
|
def parse_hosts(io)
|
79
99
|
io.each do |line|
|
80
|
-
line.sub!(/#.*/,
|
100
|
+
line.sub!(/#.*/, "")
|
81
101
|
address, hostname, *aliases = line.split(/\s+/)
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
path = System::hosts_path
|
91
|
-
|
92
|
-
if path and File.exist?(path)
|
93
|
-
File.open(path) do |file|
|
94
|
-
hosts.parse_hosts(file)
|
102
|
+
|
103
|
+
if address =~ Resolv::IPv4::Regex
|
104
|
+
address = Resolv::IPv4.create(address)
|
105
|
+
elsif address =~ Resolv::IPv6::Regex
|
106
|
+
address = Resolv::IPv6.create(address)
|
107
|
+
else
|
108
|
+
next
|
95
109
|
end
|
110
|
+
|
111
|
+
add(address, [hostname] + aliases)
|
96
112
|
end
|
97
|
-
|
98
|
-
return hosts
|
99
113
|
end
|
100
114
|
end
|
101
|
-
|
115
|
+
|
116
|
+
DEFAULT_TIMEOUT = 5.0
|
117
|
+
|
118
|
+
# Parse the `resolv.conf` file and return a list of nameservers.
|
102
119
|
def self.parse_resolv_configuration(path)
|
103
120
|
nameservers = []
|
121
|
+
search = nil
|
122
|
+
ndots = 1
|
123
|
+
edns = nil
|
124
|
+
timeout = DEFAULT_TIMEOUT
|
125
|
+
|
104
126
|
File.open(path) do |file|
|
105
127
|
file.each do |line|
|
106
128
|
# Remove any comments:
|
107
|
-
line.sub!(/[#;].*/,
|
108
|
-
|
129
|
+
line.sub!(/[#;].*/, "")
|
130
|
+
|
109
131
|
# Extract resolv.conf command:
|
110
|
-
keyword, *
|
111
|
-
|
132
|
+
keyword, *arguments = line.split(/\s+/)
|
133
|
+
|
112
134
|
case keyword
|
113
|
-
when
|
114
|
-
nameservers
|
135
|
+
when "nameserver"
|
136
|
+
nameservers.concat(arguments)
|
137
|
+
when "domain", "search"
|
138
|
+
search = arguments
|
139
|
+
when "options"
|
140
|
+
arguments.each do |argument|
|
141
|
+
key, value = argument.split(":", 2)
|
142
|
+
|
143
|
+
case key
|
144
|
+
when "ndots"
|
145
|
+
ndots = value.to_i
|
146
|
+
when "edns0"
|
147
|
+
edns = 0
|
148
|
+
when "timeout"
|
149
|
+
timeout = value.to_f
|
150
|
+
end
|
151
|
+
end
|
115
152
|
end
|
116
153
|
end
|
117
154
|
end
|
118
|
-
|
119
|
-
return
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
connections << [:udp, host, 53]
|
127
|
-
connections << [:tcp, host, 53]
|
128
|
-
end
|
129
|
-
|
130
|
-
return connections
|
155
|
+
|
156
|
+
return {
|
157
|
+
nameservers: nameservers,
|
158
|
+
search: search,
|
159
|
+
ndots: ndots,
|
160
|
+
edns: edns,
|
161
|
+
timeout: timeout,
|
162
|
+
}
|
131
163
|
end
|
132
|
-
|
164
|
+
|
133
165
|
# 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.
|
134
|
-
def self.
|
166
|
+
def self.resolver(**options)
|
135
167
|
nameservers = []
|
136
|
-
|
168
|
+
|
137
169
|
if File.exist? RESOLV_CONF
|
138
|
-
|
170
|
+
options.update(parse_resolv_configuration(RESOLV_CONF))
|
171
|
+
nameservers = options.delete(:nameservers)
|
139
172
|
elsif defined?(Win32::Resolv) and RUBY_PLATFORM =~ /mswin32|cygwin|mingw|bccwin/
|
140
173
|
search, nameservers = Win32::Resolv.get_resolv_info
|
174
|
+
options.update(search: search)
|
175
|
+
end
|
176
|
+
|
177
|
+
if search = options[:search]
|
178
|
+
unless search.include?(".")
|
179
|
+
search << nil
|
180
|
+
end
|
181
|
+
else
|
182
|
+
options[:search] = [nil]
|
183
|
+
end
|
184
|
+
|
185
|
+
if hosts = Hosts.local
|
186
|
+
cache = options.fetch(:cache) do
|
187
|
+
options[:cache] = Cache.new
|
188
|
+
end
|
189
|
+
|
190
|
+
hosts.each do |name, addresses|
|
191
|
+
addresses.each do |address|
|
192
|
+
resource = Resource.new(address, nil)
|
193
|
+
case address
|
194
|
+
when Resolv::IPv4
|
195
|
+
cache.store(name, Resolv::DNS::Resource::IN::A, resource)
|
196
|
+
when Resolv::IPv6
|
197
|
+
cache.store(name, Resolv::DNS::Resource::IN::AAAA, resource)
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
timeout = options.delete(:timeout) || DEFAULT_TIMEOUT
|
204
|
+
endpoint = Endpoint.for(nameservers, timeout: timeout)
|
205
|
+
|
206
|
+
if block_given?
|
207
|
+
yield endpoint, **options
|
208
|
+
else
|
209
|
+
return Resolver.new(endpoint, **options)
|
141
210
|
end
|
142
|
-
|
143
|
-
return standard_connections(nameservers)
|
144
211
|
end
|
145
212
|
end
|
146
213
|
end
|
@@ -1,25 +1,10 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
#
|
4
|
-
#
|
5
|
-
#
|
6
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
-
# copies of the Software, and to permit persons to whom the Software is
|
8
|
-
# furnished to do so, subject to the following conditions:
|
9
|
-
#
|
10
|
-
# The above copyright notice and this permission notice shall be included in
|
11
|
-
# all copies or substantial portions of the Software.
|
12
|
-
#
|
13
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
-
# THE SOFTWARE.
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2015-2024, by Samuel Williams.
|
5
|
+
# Copyright, 2023, by Hal Brodigan.
|
20
6
|
|
21
7
|
module Async::DNS
|
22
|
-
|
23
8
|
# This class provides all details of a single DNS question and response. This is used by the DSL to provide DNS related functionality.
|
24
9
|
#
|
25
10
|
# The main functions to complete the transaction are: {#append!} (evaluate a new query and append the results), {#passthrough!} (pass the query to an upstream server), {#respond!} (compute a specific response) and {#fail!} (fail with an error code).
|
@@ -27,7 +12,15 @@ module Async::DNS
|
|
27
12
|
# The default time used for responses (24 hours).
|
28
13
|
DEFAULT_TTL = 86400
|
29
14
|
|
30
|
-
|
15
|
+
# Create a new transaction with the given server, query, question, resource class, response, and options.
|
16
|
+
#
|
17
|
+
# @parameter server [Server] The server to use for processing.
|
18
|
+
# @parameter query [Resolv::DNS::Message] The incoming query.
|
19
|
+
# @parameter question [Resolv::DNS::Name] The question to answer.
|
20
|
+
# @parameter resource_class [Class(Resolv::DNS::Resource)] The resource class to use for responses.
|
21
|
+
# @parameter response [Resolv::DNS::Message] The response to the query.
|
22
|
+
# @parameter options [Hash] Additional options to pass to the transaction.
|
23
|
+
def initialize(server, query, question, resource_class, response, **options)
|
31
24
|
@server = server
|
32
25
|
@query = query
|
33
26
|
@question = question
|
@@ -37,21 +30,24 @@ module Async::DNS
|
|
37
30
|
@options = options
|
38
31
|
end
|
39
32
|
|
40
|
-
# The
|
33
|
+
# @attribute [Class(Resolv::DNS::Resource)] The resource class to use for responses. This is typically used to generate a response.
|
41
34
|
attr :resource_class
|
42
35
|
|
43
|
-
# The incoming query
|
36
|
+
# @attribute [Resolv::DNS::Message] The incoming query.
|
44
37
|
attr :query
|
45
38
|
|
46
|
-
# The question
|
39
|
+
# @attribute [Resolv::DNS::Name] The question to answer.
|
47
40
|
attr :question
|
48
41
|
|
49
|
-
#
|
42
|
+
# @attribute [Resolv::DNS::Message] The response to the query.
|
50
43
|
attr :response
|
51
44
|
|
52
|
-
#
|
45
|
+
# @attribute [Hash] Additional options associated with the transaction.
|
53
46
|
attr :options
|
54
47
|
|
48
|
+
# Access the options hash.
|
49
|
+
#
|
50
|
+
# @parameter key [Object] The key to lookup.
|
55
51
|
def [] key
|
56
52
|
@options[key]
|
57
53
|
end
|
@@ -68,7 +64,7 @@ module Async::DNS
|
|
68
64
|
|
69
65
|
# Run a new query through the rules with the given name and resource type. The results of this query are appended to the current transaction's `response`.
|
70
66
|
def append!(name, resource_class = nil, options = {})
|
71
|
-
Transaction.new(@server, @query, name, resource_class || @resource_class, @response, options).process
|
67
|
+
Transaction.new(@server, @query, name, resource_class || @resource_class, @response, **options).process
|
72
68
|
end
|
73
69
|
|
74
70
|
# Use the given resolver to respond to the question. Uses `passthrough` to do the lookup and merges the result.
|
@@ -78,9 +74,9 @@ module Async::DNS
|
|
78
74
|
# If recursion is not requested, the result is `fail!(:Refused)`. This check is ignored if an explicit `options[:name]` or `options[:force]` is given.
|
79
75
|
#
|
80
76
|
# If the resolver can't reach upstream servers, `fail!(:ServFail)` is invoked.
|
81
|
-
def passthrough!(resolver,
|
82
|
-
if @query.rd ||
|
83
|
-
response = passthrough(resolver, options)
|
77
|
+
def passthrough!(resolver, force: false, **options, &block)
|
78
|
+
if @query.rd || force || options[:name]
|
79
|
+
response = passthrough(resolver, **options)
|
84
80
|
|
85
81
|
if response
|
86
82
|
yield response if block_given?
|
@@ -102,11 +98,8 @@ module Async::DNS
|
|
102
98
|
# A block must be supplied, and provided a valid response is received from the upstream server, this function yields with the reply and reply_name.
|
103
99
|
#
|
104
100
|
# If `options[:name]` is provided, this overrides the default query name sent to the upstream server. The same logic applies to `options[:resource_class]`.
|
105
|
-
def passthrough(resolver,
|
106
|
-
|
107
|
-
query_resource_class = options[:resource_class] || resource_class
|
108
|
-
|
109
|
-
resolver.query(query_name, query_resource_class)
|
101
|
+
def passthrough(resolver, name: self.name, resource_class: self.resource_class)
|
102
|
+
resolver.query(name, resource_class)
|
110
103
|
end
|
111
104
|
|
112
105
|
# Respond to the given query with a resource record. The arguments to this function depend on the `resource_class` requested. This function instantiates the resource class with the supplied arguments, and then passes it to {#append!}.
|
@@ -143,7 +136,7 @@ module Async::DNS
|
|
143
136
|
ttl = options[:ttl] || DEFAULT_TTL
|
144
137
|
name = options[:name] || @question.to_s + "."
|
145
138
|
|
146
|
-
section = (options[:section] ||
|
139
|
+
section = (options[:section] || "answer").to_sym
|
147
140
|
method = "add_#{section}".to_sym
|
148
141
|
|
149
142
|
resources.each do |resource|
|
@@ -153,7 +146,7 @@ module Async::DNS
|
|
153
146
|
end
|
154
147
|
end
|
155
148
|
|
156
|
-
# This function indicates that there was a failure to resolve the given question. The single argument must be an integer error code, typically given by the constants in
|
149
|
+
# This function indicates that there was a failure to resolve the given question. The single argument must be an integer error code, typically given by the constants in `Resolv::DNS::RCode`.
|
157
150
|
#
|
158
151
|
# The easiest way to use this function it to simply supply a symbol. Here is a list of the most commonly used ones:
|
159
152
|
#
|
data/lib/async/dns/transport.rb
CHANGED
@@ -1,61 +1,49 @@
|
|
1
|
-
#
|
2
|
-
#
|
3
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
-
# of this software and associated documentation files (the "Software"), to deal
|
5
|
-
# in the Software without restriction, including without limitation the rights
|
6
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
-
# copies of the Software, and to permit persons to whom the Software is
|
8
|
-
# furnished to do so, subject to the following conditions:
|
9
|
-
#
|
10
|
-
# The above copyright notice and this permission notice shall be included in
|
11
|
-
# all copies or substantial portions of the Software.
|
12
|
-
#
|
13
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
-
# THE SOFTWARE.
|
1
|
+
# frozen_string_literal: true
|
20
2
|
|
21
|
-
|
22
|
-
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2015-2024, by Samuel Williams.
|
23
5
|
|
24
|
-
|
6
|
+
require "stringio"
|
7
|
+
require "ipaddr"
|
25
8
|
|
26
9
|
module Async
|
27
10
|
module DNS
|
28
|
-
|
29
|
-
return IPAddr.new(host).family
|
30
|
-
end
|
31
|
-
|
11
|
+
# A simple DNS message stream encoder/decoder.
|
32
12
|
class Transport
|
13
|
+
# Create a new transport.
|
14
|
+
#
|
15
|
+
# @parameter socket [IO] The socket to read/write from.
|
33
16
|
def initialize(socket)
|
34
|
-
@
|
17
|
+
@socket = socket
|
35
18
|
end
|
36
19
|
|
20
|
+
# Write a message to the socket.
|
21
|
+
#
|
22
|
+
# @parameter message [Resolv::DNS::Message] The message to write.
|
37
23
|
def write_message(message)
|
38
24
|
write_chunk(message.encode)
|
39
25
|
end
|
40
26
|
|
27
|
+
# Read a chunk from the socket.
|
28
|
+
#
|
29
|
+
# @returns [String] The data read from the socket.
|
41
30
|
def read_chunk
|
42
|
-
if size_data = @
|
31
|
+
if size_data = @socket.read(2)
|
43
32
|
# Read in the length, the first two bytes:
|
44
|
-
size = size_data.unpack(
|
33
|
+
size = size_data.unpack("n")[0]
|
45
34
|
|
46
|
-
return @
|
35
|
+
return @socket.read(size)
|
47
36
|
end
|
48
37
|
end
|
49
38
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
@
|
57
|
-
|
58
|
-
return output_data.bytesize
|
39
|
+
# Write a chunk to the socket.
|
40
|
+
#
|
41
|
+
# @parameter data [String] The data to write.
|
42
|
+
def write_chunk(data)
|
43
|
+
size_data = [data.bytesize].pack("n")
|
44
|
+
@socket.write(size_data)
|
45
|
+
@socket.write(data)
|
46
|
+
@socket.flush
|
59
47
|
end
|
60
48
|
end
|
61
49
|
end
|
data/lib/async/dns/version.rb
CHANGED
@@ -1,25 +1,11 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
#
|
4
|
-
#
|
5
|
-
#
|
6
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
-
# copies of the Software, and to permit persons to whom the Software is
|
8
|
-
# furnished to do so, subject to the following conditions:
|
9
|
-
#
|
10
|
-
# The above copyright notice and this permission notice shall be included in
|
11
|
-
# all copies or substantial portions of the Software.
|
12
|
-
#
|
13
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
-
# THE SOFTWARE.
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2012-2013, by Tony Arcieri.
|
5
|
+
# Copyright, 2015-2024, by Samuel Williams.
|
20
6
|
|
21
7
|
module Async
|
22
8
|
module DNS
|
23
|
-
VERSION =
|
9
|
+
VERSION = "1.4.0"
|
24
10
|
end
|
25
11
|
end
|
data/lib/async/dns.rb
CHANGED
@@ -1,35 +1,19 @@
|
|
1
|
-
#
|
2
|
-
#
|
3
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
-
# of this software and associated documentation files (the "Software"), to deal
|
5
|
-
# in the Software without restriction, including without limitation the rights
|
6
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
-
# copies of the Software, and to permit persons to whom the Software is
|
8
|
-
# furnished to do so, subject to the following conditions:
|
9
|
-
#
|
10
|
-
# The above copyright notice and this permission notice shall be included in
|
11
|
-
# all copies or substantial portions of the Software.
|
12
|
-
#
|
13
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
-
# THE SOFTWARE.
|
1
|
+
# frozen_string_literal: true
|
20
2
|
|
21
|
-
|
22
|
-
|
23
|
-
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2012, by Tony Arcieri.
|
5
|
+
# Copyright, 2015-2024, by Samuel Williams.
|
24
6
|
|
25
|
-
|
7
|
+
require "async"
|
8
|
+
require_relative "dns/version"
|
26
9
|
|
27
|
-
require_relative
|
28
|
-
require_relative
|
29
|
-
require_relative
|
30
|
-
require_relative 'dns/handler'
|
10
|
+
require_relative "dns/server"
|
11
|
+
require_relative "dns/resolver"
|
12
|
+
require_relative "dns/handler"
|
31
13
|
|
14
|
+
# @namespace
|
32
15
|
module Async
|
16
|
+
# @namespace
|
33
17
|
module DNS
|
34
18
|
end
|
35
19
|
end
|
data/license.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# MIT License
|
2
|
+
|
3
|
+
Copyright, 2012-2017, by Tony Arcieri.
|
4
|
+
Copyright, 2013, by Greg Thornton.
|
5
|
+
Copyright, 2014, by Hendrik Beskow.
|
6
|
+
Copyright, 2015-2025, by Samuel Williams.
|
7
|
+
Copyright, 2017-2020, by Olle Jonsson.
|
8
|
+
Copyright, 2019, by Stefan Wrobel.
|
9
|
+
Copyright, 2021, by Mike Perham.
|
10
|
+
Copyright, 2023, by Hal Brodigan.
|
11
|
+
Copyright, 2024, by Sean Dilda.
|
12
|
+
|
13
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
14
|
+
of this software and associated documentation files (the "Software"), to deal
|
15
|
+
in the Software without restriction, including without limitation the rights
|
16
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
17
|
+
copies of the Software, and to permit persons to whom the Software is
|
18
|
+
furnished to do so, subject to the following conditions:
|
19
|
+
|
20
|
+
The above copyright notice and this permission notice shall be included in all
|
21
|
+
copies or substantial portions of the Software.
|
22
|
+
|
23
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
24
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
25
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
26
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
27
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
28
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
29
|
+
SOFTWARE.
|
data/readme.md
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
# Async::DNS
|
2
|
+
|
3
|
+
Async::DNS is a high-performance DNS client resolver and server which can be easily integrated into other projects or used as a stand-alone daemon. It was forked from [RubyDNS](https://github.com/ioquatix/rubydns) which is now implemented in terms of this library.
|
4
|
+
|
5
|
+
[](https://github.com/socketry/async-dns/actions?workflow=Test)
|
6
|
+
|
7
|
+
## Usage
|
8
|
+
|
9
|
+
Please see the [project documentation](https://socketry.github.io/async-dns/) for more details.
|
10
|
+
|
11
|
+
- [Getting Started](https://socketry.github.io/async-dns/guides/getting-started/index) - This guide explains how to get started with the `async-dns` gem.
|
12
|
+
|
13
|
+
## Releases
|
14
|
+
|
15
|
+
Please see the [project releases](https://socketry.github.io/async-dns/releases/index) for all releases.
|
16
|
+
|
17
|
+
### v1.4.0
|
18
|
+
|
19
|
+
- Minimum Ruby version is now v3.1.
|
20
|
+
- Drop dependency on `Async::IO` and refactor internal network code to use `IO::Endpoint` and `Socket` directly.
|
21
|
+
- Introduce `Async::DNS::Endpoint` for getting the default endpoint for a given name server.
|
22
|
+
- Remove old hacks for IPv6 on Ruby v2.3.
|
23
|
+
- Introduce `Async::DNS::Cache` for caching DNS lookups.
|
24
|
+
- Remove `logger` as an option and instance variable in favour of using `Console.logger` directly. This is a breaking change.
|
25
|
+
- Update error logging to include more details.
|
26
|
+
- Use keyword arguments `**options` where possible. This is a breaking change.
|
27
|
+
- `Async::DNS::StreamHandler` and `Async::DNS::DatagramHandler` have been refactored to use `IO::Endpoint` and have minor breaking interface changes.
|
28
|
+
- `Async::DNS::Resolver.default` should be used to get a default resolver instance.
|
29
|
+
- The resolver now supports `ndots:` when resolving names.
|
30
|
+
- `Async::DNS::Resolver#fully_qualified_name` is replaced by `Async::DNS::Resolver#fully_qualified_names` and can yield multiple names.
|
31
|
+
- If the host system supports IPv6, the resolver will also try to resolve IPv6 addresses.
|
32
|
+
- `Async::DNS::Server::DEFAULT_ENDPOINTS` is removed and replaced by `Async::DNS::Server.default_endpoint(port = 53)`.
|
33
|
+
- `Async::DNS::Server#fire` is removed with no replacement.
|
34
|
+
- The default `Async::DNS::Server#process` fails with `NXDomain` instead of `NotImplementedError`.
|
35
|
+
- `Async::DNS::System` implementation is updated to support IPv6 and `resolv.conf` options.
|
36
|
+
|
37
|
+
## Contributing
|
38
|
+
|
39
|
+
We welcome contributions to this project.
|
40
|
+
|
41
|
+
1. Fork it.
|
42
|
+
2. Create your feature branch (`git checkout -b my-new-feature`).
|
43
|
+
3. Commit your changes (`git commit -am 'Add some feature'`).
|
44
|
+
4. Push to the branch (`git push origin my-new-feature`).
|
45
|
+
5. Create new Pull Request.
|
46
|
+
|
47
|
+
### Developer Certificate of Origin
|
48
|
+
|
49
|
+
In order to protect users of this project, we require all contributors to comply with the [Developer Certificate of Origin](https://developercertificate.org/). This ensures that all contributions are properly licensed and attributed.
|
50
|
+
|
51
|
+
### Community Guidelines
|
52
|
+
|
53
|
+
This project is best served by a collaborative and respectful environment. Treat each other professionally, respect differing viewpoints, and engage constructively. Harassment, discrimination, or harmful behavior is not tolerated. Communicate clearly, listen actively, and support one another. If any issues arise, please inform the project maintainers.
|