async-dns 1.2.6 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,25 +1,12 @@
1
- # Copyright, 2009, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
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
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 'win32/resolv'
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
- # This code is very experimental
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
- attr :addresses
49
- attr :names
50
-
51
- # This is used to match names against the list of known hosts:
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
- add(address, [hostname] + aliases)
84
- end
85
- end
86
-
87
- def self.local
88
- hosts = self.new
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, *args = line.split(/\s+/)
111
-
132
+ keyword, *arguments = line.split(/\s+/)
133
+
112
134
  case keyword
113
- when 'nameserver'
114
- nameservers += args
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 nameservers
120
- end
121
-
122
- def self.standard_connections(nameservers)
123
- connections = []
124
-
125
- nameservers.each do |host|
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.nameservers
166
+ def self.resolver(**options)
135
167
  nameservers = []
136
-
168
+
137
169
  if File.exist? RESOLV_CONF
138
- nameservers = parse_resolv_configuration(RESOLV_CONF)
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
- # Copyright, 2009, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
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
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
- def initialize(server, query, question, resource_class, response, options = {})
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 resource_class that was requested. This is typically used to generate a response.
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 which is a set of questions.
36
+ # @attribute [Resolv::DNS::Message] The incoming query.
44
37
  attr :query
45
38
 
46
- # The question that this transaction represents.
39
+ # @attribute [Resolv::DNS::Name] The question to answer.
47
40
  attr :question
48
41
 
49
- # The current full response to the incoming query.
42
+ # @attribute [Resolv::DNS::Message] The response to the query.
50
43
  attr :response
51
44
 
52
- # Any options or configuration associated with the given transaction.
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, options = {}, &block)
82
- if @query.rd || options[:force] || options[:name]
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, options = {})
106
- query_name = options[:name] || name
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] || 'answer').to_sym
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 {Resolv::DNS::RCode}.
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
  #
@@ -1,61 +1,49 @@
1
- # Copyright, 2009, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
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
- require 'stringio'
22
- require 'ipaddr'
3
+ # Released under the MIT License.
4
+ # Copyright, 2015-2024, by Samuel Williams.
23
5
 
24
- require_relative 'message'
6
+ require "stringio"
7
+ require "ipaddr"
25
8
 
26
9
  module Async
27
10
  module DNS
28
- def self.address_family(host)
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
- @stream = IO::Stream.new(socket)
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 = @stream.read(2)
31
+ if size_data = @socket.read(2)
43
32
  # Read in the length, the first two bytes:
44
- size = size_data.unpack('n')[0]
33
+ size = size_data.unpack("n")[0]
45
34
 
46
- return @stream.read(size)
35
+ return @socket.read(size)
47
36
  end
48
37
  end
49
38
 
50
- def write_chunk(output_data)
51
- size_data = [output_data.bytesize].pack('n')
52
-
53
- @stream.write(size_data)
54
- @stream.write(output_data)
55
-
56
- @stream.flush
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
@@ -1,25 +1,11 @@
1
- # Copyright, 2009, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
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
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 = '1.2.6'
9
+ VERSION = "1.4.0"
24
10
  end
25
11
  end
data/lib/async/dns.rb CHANGED
@@ -1,35 +1,19 @@
1
- # Copyright, 2009, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
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
- require 'async'
22
- require 'async/io/tcp_socket'
23
- require 'async/io/udp_socket'
3
+ # Released under the MIT License.
4
+ # Copyright, 2012, by Tony Arcieri.
5
+ # Copyright, 2015-2024, by Samuel Williams.
24
6
 
25
- require_relative 'dns/version'
7
+ require "async"
8
+ require_relative "dns/version"
26
9
 
27
- require_relative 'dns/message'
28
- require_relative 'dns/server'
29
- require_relative 'dns/resolver'
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
+ [![Development Status](https://github.com/socketry/async-dns/workflows/Test/badge.svg)](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.