dnsruby 1.70.0 → 1.74.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/FUNDING.yml +3 -0
- data/.github/dependabot.yml +11 -0
- data/.github/workflows/ci.yml +10 -7
- data/RELEASE_NOTES.md +50 -0
- data/cache_delay.rb +20 -0
- data/demo/rubydig.rb +2 -0
- data/dnsruby.gemspec +10 -8
- data/fd.ruby +33 -0
- data/lib/dnsruby/bit_mapping.rb +2 -2
- data/lib/dnsruby/cache.rb +0 -2
- data/lib/dnsruby/code_mappers.rb +3 -2
- data/lib/dnsruby/config.rb +2 -5
- data/lib/dnsruby/hosts.rb +0 -7
- data/lib/dnsruby/ipv6.rb +5 -5
- data/lib/dnsruby/message/encoder.rb +1 -1
- data/lib/dnsruby/message/message.rb +2 -2
- data/lib/dnsruby/packet_sender.rb +19 -4
- data/lib/dnsruby/recursor.rb +7 -6
- data/lib/dnsruby/resolver.rb +40 -17
- data/lib/dnsruby/resource/CAA.rb +5 -2
- data/lib/dnsruby/resource/DNSKEY.rb +15 -8
- data/lib/dnsruby/resource/GPOS.rb +1 -1
- data/lib/dnsruby/resource/IN.rb +2 -2
- data/lib/dnsruby/resource/NSEC.rb +2 -2
- data/lib/dnsruby/resource/NXT.rb +1 -1
- data/lib/dnsruby/resource/OPT.rb +2 -3
- data/lib/dnsruby/resource/TXT.rb +1 -1
- data/lib/dnsruby/select_thread.rb +43 -27
- data/lib/dnsruby/single_verifier.rb +1 -1
- data/lib/dnsruby/version.rb +1 -1
- data/test/spec_helper.rb +22 -3
- data/test/tc_caa.rb +13 -0
- data/test/tc_dns.rb +13 -13
- data/test/tc_ecdsa.rb +27 -0
- data/test/tc_escapedchars.rb +8 -9
- data/test/tc_gpos.rb +1 -1
- data/test/tc_hs.rb +0 -5
- data/test/tc_message.rb +2 -2
- data/test/tc_name.rb +2 -2
- data/test/tc_nxt.rb +0 -1
- data/test/tc_recur.rb +4 -7
- data/test/tc_res_config.rb +29 -0
- data/test/tc_resolv.rb +11 -4
- data/test/tc_resolver.rb +93 -3
- data/test/tc_rr-unknown.rb +1 -1
- data/test/tc_rr.rb +4 -4
- data/test/tc_single_resolver.rb +9 -17
- data/test/tc_tcp_pipelining.rb +3 -3
- data/test/tc_tkey.rb +1 -7
- data/test/tc_update.rb +0 -1
- metadata +60 -9
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 31fc09cb1cf4b1c2174c67a16e96601eb25c6509e6525c3cef9159da5fd656c2
|
|
4
|
+
data.tar.gz: e96495f35da0ff50636052f3f27623b4fc620572c0c4109f6c47a5a81eb77801
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 84c58dc7dbf8d3c33d11ee7ea10d076d806cf1700c327b5e84fbebac08484fba8179734dbe9631c85daec38518b29ca3d8e3a29629d71a69a955f615bdf60346
|
|
7
|
+
data.tar.gz: 06b7c82e2b1e979f1c18aaa9567596f6724a7fb5eae8da688921958506ab9cc9ed1657f168699ec6a0112c3c25afcba419d333b7f3b4f618537fa6e6f1ee91c7
|
data/.github/FUNDING.yml
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# To get started with Dependabot version updates, you'll need to specify which
|
|
2
|
+
# package ecosystems to update and where the package manifests are located.
|
|
3
|
+
# Please see the documentation for all configuration options:
|
|
4
|
+
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
|
|
5
|
+
|
|
6
|
+
version: 2
|
|
7
|
+
updates:
|
|
8
|
+
- package-ecosystem: "bundler" # See documentation for possible values
|
|
9
|
+
directory: "/" # Location of package manifests
|
|
10
|
+
schedule:
|
|
11
|
+
interval: "weekly"
|
data/.github/workflows/ci.yml
CHANGED
|
@@ -6,8 +6,14 @@ jobs:
|
|
|
6
6
|
build:
|
|
7
7
|
runs-on: ubuntu-latest
|
|
8
8
|
strategy:
|
|
9
|
+
fail-fast: false
|
|
9
10
|
matrix:
|
|
10
|
-
ruby: [ '
|
|
11
|
+
ruby: [ '3.2.10', '3.3.11', '3.4.10', '4.0.5' ] # , 'ruby-head' ]
|
|
12
|
+
rubyopt: ['']
|
|
13
|
+
include:
|
|
14
|
+
- ruby: '3.4'
|
|
15
|
+
rubyopt: "--enable-frozen-string-literal --debug-frozen-string-literal"
|
|
16
|
+
|
|
11
17
|
name: Ruby ${{ matrix.ruby }} tests
|
|
12
18
|
steps:
|
|
13
19
|
- uses: actions/checkout@v2
|
|
@@ -15,9 +21,6 @@ jobs:
|
|
|
15
21
|
uses: ruby/setup-ruby@v1
|
|
16
22
|
with:
|
|
17
23
|
ruby-version: ${{ matrix.ruby }}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
bundle install --jobs 4 --retry 3
|
|
22
|
-
- name: Run tests
|
|
23
|
-
run: bundle exec rake test
|
|
24
|
+
bundler-cache: true
|
|
25
|
+
- name: Run tests ${{ matrix.rubyopt }}
|
|
26
|
+
run: bundle exec rake test RUBYOPT="${{ matrix.rubyopt }}"
|
data/RELEASE_NOTES.md
CHANGED
|
@@ -1,5 +1,55 @@
|
|
|
1
1
|
# Release Notes
|
|
2
2
|
|
|
3
|
+
## v1.74.0
|
|
4
|
+
|
|
5
|
+
* Resolve all configured nameservers in parallel
|
|
6
|
+
* Only raise ArgumentError from Resolver if _all_ configured nameservers are invalid - otherwise, just log the bad one(s) and continue
|
|
7
|
+
* print out extra OPT data
|
|
8
|
+
* Fix wakeup socket deletion on stopping of select thread
|
|
9
|
+
* Make sure to add nameservers if using config_info in Resolver
|
|
10
|
+
* Fix for RRSET pruning and potential cache poisoning - thanks Alexander Tan
|
|
11
|
+
* Fix WKS record protocol field encoding and decoding size according to RFC 1035 Section 3.4.2 where PROTOCOL is an 8 bit (#220)
|
|
12
|
+
* Updating workflows to include Ruby 4, and get rdoc working for it
|
|
13
|
+
|
|
14
|
+
## v1.73.1
|
|
15
|
+
|
|
16
|
+
* fix(caa): add support for issuevmc (#214) - thanks Mark McDonnell!
|
|
17
|
+
|
|
18
|
+
## v1.73.0
|
|
19
|
+
|
|
20
|
+
* Ruby 3.4 updates - thanks @zarqman!
|
|
21
|
+
* Enable setting up a custom UDP size when DNSSEC validation is disabled
|
|
22
|
+
* EDNS OPT RR for udp_size > 512 - thanks @mrideout!
|
|
23
|
+
* Test code improvements - thanks @mrideout!
|
|
24
|
+
* base64 gem version fixes
|
|
25
|
+
* Fix for file descriptor leak on truncated UDP messages
|
|
26
|
+
|
|
27
|
+
## v1.72.4
|
|
28
|
+
|
|
29
|
+
* allow parsing case insensitive property tags for CAA records - thanks ruby-dev!
|
|
30
|
+
* Add logger as a dependency for Ruby 3.5.0+ support - thanks Alexandre ZANNI!
|
|
31
|
+
|
|
32
|
+
## v1.72.3
|
|
33
|
+
|
|
34
|
+
* Fix cached answer response time - thanks Andre Meij!
|
|
35
|
+
* Add base64 as a dependency for Ruby 3.4.0+ support - thanks Alexandre ZANNI!
|
|
36
|
+
|
|
37
|
+
## v1.72.2
|
|
38
|
+
|
|
39
|
+
* Invalid CAA handling fixes - thanks Noah Smethwick and Ryan Doherty!
|
|
40
|
+
|
|
41
|
+
## v.1.72.1
|
|
42
|
+
|
|
43
|
+
* Add issuemail CAA record support - thanks Ryan Doherty!
|
|
44
|
+
|
|
45
|
+
## v.1.72.0
|
|
46
|
+
|
|
47
|
+
* Fix compatibility with the `--enable-string-literal` Ruby option - thanks Jean byroot Boussier!
|
|
48
|
+
|
|
49
|
+
## v.1.71.0
|
|
50
|
+
|
|
51
|
+
* Fix assigning public_key in ECDSA - thanks Jiří Kubíček!
|
|
52
|
+
|
|
3
53
|
## v.1.70.0
|
|
4
54
|
|
|
5
55
|
* OpenSSL 3 support
|
data/cache_delay.rb
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require "dnsruby"
|
|
2
|
+
Dnsruby::TheLog.level = Logger::DEBUG
|
|
3
|
+
|
|
4
|
+
def testme
|
|
5
|
+
domain1 = "example.com"
|
|
6
|
+
domain2 = "example.net"
|
|
7
|
+
|
|
8
|
+
start_time = Time.now
|
|
9
|
+
resolver = Dnsruby::Resolver.new
|
|
10
|
+
resolver.query(domain1)
|
|
11
|
+
puts "First query time: #{Time.now - start_time} seconds"
|
|
12
|
+
|
|
13
|
+
start_time = Time.now
|
|
14
|
+
resolver = Dnsruby::Resolver.new
|
|
15
|
+
resolver.query(domain2)
|
|
16
|
+
puts "Second query time: #{Time.now - start_time} seconds"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
testme
|
|
20
|
+
testme
|
data/demo/rubydig.rb
CHANGED
|
@@ -60,6 +60,8 @@ if ARGV[0] =~ /^@/
|
|
|
60
60
|
else
|
|
61
61
|
puts "Setting nameserver : #{nameserver}"
|
|
62
62
|
resolver.nameserver = (nameserver.sub(/^@/, ''))
|
|
63
|
+
resolver.dnssec = true
|
|
64
|
+
resolver.do_validation = true
|
|
63
65
|
puts "nameservers = #{resolver.config.nameserver}"
|
|
64
66
|
zone_transfer.server = (nameserver.sub(/^@/, ''))
|
|
65
67
|
end
|
data/dnsruby.gemspec
CHANGED
|
@@ -15,7 +15,10 @@ SPEC = Gem::Specification.new do |s|
|
|
|
15
15
|
stub resolver. It aims to comply with all DNS RFCs, including
|
|
16
16
|
DNSSEC NSEC3 support.'
|
|
17
17
|
s.license = "Apache License, Version 2.0"
|
|
18
|
-
|
|
18
|
+
|
|
19
|
+
# Add explicit Ruby version requirement
|
|
20
|
+
s.required_ruby_version = '>= 2.8.0'
|
|
21
|
+
|
|
19
22
|
s.files = `git ls-files -z`.split("\x0")
|
|
20
23
|
|
|
21
24
|
s.post_install_message = \
|
|
@@ -36,16 +39,15 @@ DNSSEC NSEC3 support.'
|
|
|
36
39
|
}
|
|
37
40
|
|
|
38
41
|
s.add_development_dependency 'rake', '>= 13.0.6'
|
|
39
|
-
s.add_development_dependency 'minitest', '~> 5.
|
|
42
|
+
s.add_development_dependency 'minitest', '~> 5.25'
|
|
40
43
|
s.add_development_dependency 'rubydns', '>= 2.0.2'
|
|
41
44
|
s.add_development_dependency 'nio4r', '>= 2.5.8'
|
|
42
45
|
s.add_development_dependency 'minitest-display', '>= 0.3.1'
|
|
43
|
-
s.add_development_dependency
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
if RUBY_VERSION >= "1.9.3"
|
|
47
|
-
s.add_development_dependency 'coveralls', '~> 0.8.23'
|
|
48
|
-
end
|
|
46
|
+
s.add_development_dependency 'rdoc', '>= 6.5', '< 8.0'
|
|
47
|
+
s.add_development_dependency 'yard', '>= 0.9'
|
|
48
|
+
s.add_development_dependency 'coveralls', '~> 0.8.23'
|
|
49
49
|
|
|
50
|
+
s.add_runtime_dependency 'base64', '>= 0.2'
|
|
51
|
+
s.add_runtime_dependency 'logger', '~> 1.6'
|
|
50
52
|
s.add_runtime_dependency 'simpleidn', '~> 0.2.1'
|
|
51
53
|
end
|
data/fd.ruby
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
# frozen_string_literal: true
|
|
4
|
+
|
|
5
|
+
require 'dnsruby'
|
|
6
|
+
require 'thread'
|
|
7
|
+
|
|
8
|
+
#Dnsruby.log.level = Logger::DEBUG
|
|
9
|
+
|
|
10
|
+
# speed up the repro
|
|
11
|
+
NFILES = 30
|
|
12
|
+
nfiles, _ = Process.getrlimit(Process::RLIMIT_NOFILE)
|
|
13
|
+
Process.setrlimit(Process::RLIMIT_NOFILE, NFILES) if nfiles > NFILES
|
|
14
|
+
|
|
15
|
+
NAMESERVERS = ["192.31.80.30"]
|
|
16
|
+
|
|
17
|
+
Thread.new {
|
|
18
|
+
res = Dnsruby::Resolver.new(nameserver: NAMESERVERS, do_caching: false, query_timeout: 5)
|
|
19
|
+
loop do
|
|
20
|
+
begin
|
|
21
|
+
res.query("blahblahblah.com.edgekey.net", "CNAME")
|
|
22
|
+
rescue Dnsruby::ResolvError
|
|
23
|
+
end
|
|
24
|
+
sleep 0.2
|
|
25
|
+
end
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
loop do
|
|
29
|
+
# system("ls -l /proc/#{Process.pid}/fd/")
|
|
30
|
+
system("lsof -p #{Process.pid} | wc -l")
|
|
31
|
+
File.open("/") { |_| }
|
|
32
|
+
sleep 1
|
|
33
|
+
end
|
data/lib/dnsruby/bit_mapping.rb
CHANGED
|
@@ -15,7 +15,7 @@ module Dnsruby
|
|
|
15
15
|
|
|
16
16
|
# Converts from a binary string to a number, e.g. "\x01\x00" => 256
|
|
17
17
|
def binary_string_to_number(string)
|
|
18
|
-
string = string.
|
|
18
|
+
string = string.b
|
|
19
19
|
string.bytes.inject(0) do |number, byte|
|
|
20
20
|
number * 256 + byte.ord
|
|
21
21
|
end
|
|
@@ -25,7 +25,7 @@ module Dnsruby
|
|
|
25
25
|
# Converts a number to a binary encoded string, e.g. 256 => "\x01\x00"
|
|
26
26
|
def number_to_binary_string(number, min_length = 0)
|
|
27
27
|
assert_non_negative(number)
|
|
28
|
-
binary_string = ''.
|
|
28
|
+
binary_string = ''.b
|
|
29
29
|
|
|
30
30
|
while number > 0
|
|
31
31
|
byte_value = number & 0xFF
|
data/lib/dnsruby/cache.rb
CHANGED
|
@@ -68,14 +68,12 @@ module Dnsruby
|
|
|
68
68
|
# This method "fixes up" the response, so that the header and ttls are OK
|
|
69
69
|
# The resolver will still need to copy the flags and ID across from the query
|
|
70
70
|
def find(qname, qtype, qclass = Classes.IN)
|
|
71
|
-
# print "CACHE find : #{qname}, #{qtype}\n"
|
|
72
71
|
qn = Name.create(qname)
|
|
73
72
|
qn.absolute = true
|
|
74
73
|
key = CacheKey.new(qn, qtype, qclass).to_s
|
|
75
74
|
@mutex.synchronize {
|
|
76
75
|
data = @cache[key]
|
|
77
76
|
if (!data)
|
|
78
|
-
# print "CACHE lookup failed\n"
|
|
79
77
|
return nil
|
|
80
78
|
end
|
|
81
79
|
if (data.expiration <= Time.now.to_i)
|
data/lib/dnsruby/code_mappers.rb
CHANGED
|
@@ -70,7 +70,8 @@ module Dnsruby
|
|
|
70
70
|
# (RFC3597)
|
|
71
71
|
# See typesbyval and typesbyname, these beasts have the same functionality
|
|
72
72
|
def Classes.classesbyname(name) #:nodoc: all
|
|
73
|
-
name.upcase
|
|
73
|
+
name = name.upcase
|
|
74
|
+
|
|
74
75
|
if to_code(name)
|
|
75
76
|
return to_code(name)
|
|
76
77
|
end
|
|
@@ -202,7 +203,7 @@ module Dnsruby
|
|
|
202
203
|
# mnemonic. If the TYPE mapping is not specified the generic mnemonic
|
|
203
204
|
# TYPE### is returned.
|
|
204
205
|
def Types.typesbyname(name) #:nodoc: all
|
|
205
|
-
name.upcase
|
|
206
|
+
name = name.upcase
|
|
206
207
|
|
|
207
208
|
if to_code(name)
|
|
208
209
|
return to_code(name)
|
data/lib/dnsruby/config.rb
CHANGED
|
@@ -294,6 +294,8 @@ module Dnsruby
|
|
|
294
294
|
end
|
|
295
295
|
}
|
|
296
296
|
if (!found)
|
|
297
|
+
# Log the error, in case Resolver is resolving a set of nameservers, and swallows the exception
|
|
298
|
+
TheLog.error{"Recursor can't locate #{server}"}
|
|
297
299
|
raise ArgumentError.new("Recursor can't locate #{server}")
|
|
298
300
|
end
|
|
299
301
|
end
|
|
@@ -318,11 +320,6 @@ module Dnsruby
|
|
|
318
320
|
f.each {|line|
|
|
319
321
|
line.sub!(/[#;].*/, '')
|
|
320
322
|
keyword, *args = line.split(/\s+/)
|
|
321
|
-
if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("2.8")
|
|
322
|
-
args.each { |arg|
|
|
323
|
-
arg.untaint
|
|
324
|
-
}
|
|
325
|
-
end
|
|
326
323
|
next unless keyword
|
|
327
324
|
case keyword
|
|
328
325
|
when 'port'
|
data/lib/dnsruby/hosts.rb
CHANGED
|
@@ -57,19 +57,12 @@ module Dnsruby
|
|
|
57
57
|
line.sub!(/#.*/, '')
|
|
58
58
|
addr, hostname, *aliases = line.split(/\s+/)
|
|
59
59
|
next unless addr
|
|
60
|
-
if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("2.8")
|
|
61
|
-
addr.untaint
|
|
62
|
-
hostname.untaint
|
|
63
|
-
end
|
|
64
60
|
@addr2name[addr] = [] unless @addr2name.include? addr
|
|
65
61
|
@addr2name[addr] << hostname
|
|
66
62
|
@addr2name[addr] += aliases
|
|
67
63
|
@name2addr[hostname] = [] unless @name2addr.include? hostname
|
|
68
64
|
@name2addr[hostname] << addr
|
|
69
65
|
aliases.each {|n|
|
|
70
|
-
if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("2.8")
|
|
71
|
-
n.untaint
|
|
72
|
-
end
|
|
73
66
|
@name2addr[n] = [] unless @name2addr.include? n
|
|
74
67
|
@name2addr[n] << addr
|
|
75
68
|
}
|
data/lib/dnsruby/ipv6.rb
CHANGED
|
@@ -57,14 +57,14 @@ module Dnsruby
|
|
|
57
57
|
when IPv6
|
|
58
58
|
return arg
|
|
59
59
|
when String
|
|
60
|
-
address = ''
|
|
60
|
+
address = +''
|
|
61
61
|
if Regex_8Hex =~ arg
|
|
62
62
|
arg.scan(/[0-9A-Fa-f]+/) {|hex| address << [hex.hex].pack('n')}
|
|
63
63
|
elsif Regex_CompressedHex =~ arg
|
|
64
64
|
prefix = $1
|
|
65
65
|
suffix = $2
|
|
66
|
-
a1 = ''
|
|
67
|
-
a2 = ''
|
|
66
|
+
a1 = +''
|
|
67
|
+
a2 = +''
|
|
68
68
|
prefix.scan(/[0-9A-Fa-f]+/) {|hex| a1 << [hex.hex].pack('n')}
|
|
69
69
|
suffix.scan(/[0-9A-Fa-f]+/) {|hex| a2 << [hex.hex].pack('n')}
|
|
70
70
|
omitlen = 16 - a1.length - a2.length
|
|
@@ -80,8 +80,8 @@ module Dnsruby
|
|
|
80
80
|
elsif Regex_CompressedHex4Dec =~ arg
|
|
81
81
|
prefix, suffix, a, b, c, d = $1, $2, $3.to_i, $4.to_i, $5.to_i, $6.to_i
|
|
82
82
|
if (0..255) === a && (0..255) === b && (0..255) === c && (0..255) === d
|
|
83
|
-
a1 = ''
|
|
84
|
-
a2 = ''
|
|
83
|
+
a1 = +''
|
|
84
|
+
a2 = +''
|
|
85
85
|
prefix.scan(/[0-9A-Fa-f]+/) {|hex| a1 << [hex.hex].pack('n')}
|
|
86
86
|
suffix.scan(/[0-9A-Fa-f]+/) {|hex| a2 << [hex.hex].pack('n')}
|
|
87
87
|
omitlen = 12 - a1.length - a2.length
|
|
@@ -408,7 +408,7 @@ module Dnsruby
|
|
|
408
408
|
end
|
|
409
409
|
|
|
410
410
|
def to_s
|
|
411
|
-
s = '' # the output string to return
|
|
411
|
+
s = +'' # the output string to return
|
|
412
412
|
|
|
413
413
|
if @answerfrom && (! @answerfrom.empty?)
|
|
414
414
|
s << ";; Answer received from #{@answerfrom} (#{@answersize} bytes)\n;;\n"
|
|
@@ -457,7 +457,7 @@ module Dnsruby
|
|
|
457
457
|
|
|
458
458
|
|
|
459
459
|
def old_to_s
|
|
460
|
-
retval = ''
|
|
460
|
+
retval = +''
|
|
461
461
|
|
|
462
462
|
if (@answerfrom != nil && @answerfrom != '')
|
|
463
463
|
retval = retval + ";; Answer received from #{@answerfrom} (#{@answersize} bytes)\n;;\n"
|
|
@@ -204,6 +204,7 @@ module Dnsruby
|
|
|
204
204
|
@tcp_pipelining_max_queries = :infinite
|
|
205
205
|
@use_counts = {}
|
|
206
206
|
|
|
207
|
+
ignore_config_resolv_errors = false;
|
|
207
208
|
if arg.nil?
|
|
208
209
|
elsif arg.kind_of? String
|
|
209
210
|
@server = arg
|
|
@@ -212,10 +213,14 @@ module Dnsruby
|
|
|
212
213
|
elsif arg.kind_of? Hash
|
|
213
214
|
arg.keys.each do |attr|
|
|
214
215
|
begin
|
|
215
|
-
if (
|
|
216
|
-
|
|
216
|
+
if (attr.to_s == "ignore_config_resolv_errors")
|
|
217
|
+
ignore_config_resolv_errors = arg[attr]
|
|
217
218
|
else
|
|
218
|
-
|
|
219
|
+
if ((attr.to_s == "src_address" || attr.to_s == "src_address6") &&
|
|
220
|
+
(arg[attr] == nil || arg[attr] == ""))
|
|
221
|
+
else
|
|
222
|
+
send(attr.to_s + "=", arg[attr])
|
|
223
|
+
end
|
|
219
224
|
end
|
|
220
225
|
rescue Exception => e
|
|
221
226
|
Dnsruby.log.error { "PacketSender : Argument #{attr}, #{arg[attr]} not valid : #{e}\n" }
|
|
@@ -223,7 +228,17 @@ module Dnsruby
|
|
|
223
228
|
end
|
|
224
229
|
end
|
|
225
230
|
# Check server is IP
|
|
226
|
-
|
|
231
|
+
# We should allow the call of PacketSender.new to flag just to log an error if this fails
|
|
232
|
+
# and then return null
|
|
233
|
+
if ignore_config_resolv_errors
|
|
234
|
+
begin
|
|
235
|
+
@server=Config.resolve_server(@server)
|
|
236
|
+
rescue ArgumentError
|
|
237
|
+
return
|
|
238
|
+
end
|
|
239
|
+
else
|
|
240
|
+
@server=Config.resolve_server(@server)
|
|
241
|
+
end
|
|
227
242
|
|
|
228
243
|
check_ipv6
|
|
229
244
|
# ResolverRegister::register_single_resolver(self)
|
data/lib/dnsruby/recursor.rb
CHANGED
|
@@ -500,7 +500,7 @@ module Dnsruby
|
|
|
500
500
|
return nil
|
|
501
501
|
end
|
|
502
502
|
|
|
503
|
-
known_zone.sub
|
|
503
|
+
known_zone = known_zone.sub(/\.*$/, ".")
|
|
504
504
|
|
|
505
505
|
ns = [] # Array of AddressCaches (was array of array of addresses)
|
|
506
506
|
@@mutex.synchronize{
|
|
@@ -678,7 +678,8 @@ module Dnsruby
|
|
|
678
678
|
if (of.length <= known_zone.length)
|
|
679
679
|
TheLog.debug(";; _dorecursion() Deadbeat name server did not provide new information.")
|
|
680
680
|
next
|
|
681
|
-
elsif (of =~ /#{known_zone}/)
|
|
681
|
+
# elsif (of =~ /#{known_zone}/)
|
|
682
|
+
elsif (of == known_zone || known_zone.length == 1 || of.end_with?(".#{known_zone}"))
|
|
682
683
|
TheLog.debug(";; _dorecursion() FOUND closer authority for [#{of}] at [#{server}].")
|
|
683
684
|
auth[server] ||= AddressCache.new #[] @TODO@ If there is no additional record for this, then we want to use the authority!
|
|
684
685
|
if (rr.type == Types.NS)
|
|
@@ -688,7 +689,7 @@ module Dnsruby
|
|
|
688
689
|
end
|
|
689
690
|
end
|
|
690
691
|
else
|
|
691
|
-
TheLog.debug(";; _dorecursion() Confused name server [" + @answerfrom + "] thinks
|
|
692
|
+
TheLog.debug(";; _dorecursion() Confused name server [" + @answerfrom.to_s + "] thinks " + of.to_s + " is closer than " + known_zone.to_s + "?")
|
|
692
693
|
return nil
|
|
693
694
|
end
|
|
694
695
|
else
|
|
@@ -750,9 +751,9 @@ module Dnsruby
|
|
|
750
751
|
# Now prune the response of any unrelated rrsets (RFC5452 section6)
|
|
751
752
|
# "One very simple way to achieve this is to only accept data if it is
|
|
752
753
|
# part of the domain for which the query was intended."
|
|
753
|
-
if (!packet.header.aa)
|
|
754
|
-
|
|
755
|
-
end
|
|
754
|
+
# if (!packet.header.aa)
|
|
755
|
+
# return
|
|
756
|
+
# end
|
|
756
757
|
if (!packet.question()[0])
|
|
757
758
|
return
|
|
758
759
|
end
|
data/lib/dnsruby/resolver.rb
CHANGED
|
@@ -299,15 +299,17 @@ module Dnsruby
|
|
|
299
299
|
# is sent (TSIG signatures will be applied if configured on the Resolver).
|
|
300
300
|
# Retries are handled as the Resolver is configured to do.
|
|
301
301
|
# Incoming responses to the query are not cached or validated (although TCP
|
|
302
|
-
# fallback will be performed if the TC bit is set and the (Single)Resolver
|
|
303
|
-
# ignore_truncation set to false).
|
|
304
|
-
# Note that the Message
|
|
305
|
-
#
|
|
306
|
-
#
|
|
307
|
-
#
|
|
308
|
-
#
|
|
309
|
-
#
|
|
310
|
-
#
|
|
302
|
+
# fallback will be performed if the TC bit is set and the (Single)Resolver
|
|
303
|
+
# has ignore_truncation set to false).
|
|
304
|
+
# Note that the Message may be modified before sending: if the configured
|
|
305
|
+
# udp_size is >512 bytes, DNSSEC is not set, and no OPT record is already
|
|
306
|
+
# present, then an OPT record will be added automatically to support EDNS
|
|
307
|
+
# per RFC 6891.
|
|
308
|
+
# If it is desired to customize the OPT record or use EDNS in other cases,
|
|
309
|
+
# then you should call the Dnsruby::PacketSender#prepare_for_dnssec(msg),
|
|
310
|
+
# or Dnsruby::PacketSender#add_opt_rr(msg).
|
|
311
|
+
# The return value from this method is the [response, error] tuple. Either
|
|
312
|
+
# of these values may be nil - it is up to the client to check.
|
|
311
313
|
#
|
|
312
314
|
# example :
|
|
313
315
|
#
|
|
@@ -399,7 +401,7 @@ module Dnsruby
|
|
|
399
401
|
if @single_resolvers.length == 0
|
|
400
402
|
Thread.start {
|
|
401
403
|
sleep(@query_timeout == 0 ? 1 : @query_timeout)
|
|
402
|
-
client_queue.push([client_query_id, nil, ResolvTimeout.new('Query timed out - no nameservers configured')])
|
|
404
|
+
client_queue.push([client_query_id, nil, ResolvTimeout.new('Query timed out - no valid nameservers configured')])
|
|
403
405
|
}
|
|
404
406
|
end
|
|
405
407
|
client_query_id
|
|
@@ -434,7 +436,7 @@ module Dnsruby
|
|
|
434
436
|
# * :tcp_pipelining
|
|
435
437
|
# * :tcp_pipelining_max_queries - can be a number or :infinite symbol
|
|
436
438
|
def initialize(*args)
|
|
437
|
-
# @TODO@ Should we allow :
|
|
439
|
+
# @TODO@ Should we allow :nameserver to be an RRSet of NS records? Would then need to randomly order them?
|
|
438
440
|
@resolver_ruby = nil
|
|
439
441
|
@src_address = nil
|
|
440
442
|
@src_address6 = nil
|
|
@@ -451,6 +453,7 @@ module Dnsruby
|
|
|
451
453
|
begin
|
|
452
454
|
if key == :config_info
|
|
453
455
|
@config.set_config_info(args[0][:config_info])
|
|
456
|
+
add_config_nameservers
|
|
454
457
|
elsif key == :nameserver
|
|
455
458
|
set_config_nameserver(args[0][:nameserver])
|
|
456
459
|
elsif key == :nameservers
|
|
@@ -479,10 +482,11 @@ module Dnsruby
|
|
|
479
482
|
@config.get_ready
|
|
480
483
|
end
|
|
481
484
|
@configured = true
|
|
482
|
-
@single_res_mutex.synchronize {
|
|
483
485
|
# Add the Config nameservers
|
|
484
|
-
|
|
485
|
-
|
|
486
|
+
threads = []
|
|
487
|
+
@config.nameserver.each do |ns|
|
|
488
|
+
threads << Thread.new do
|
|
489
|
+
PacketSender.new({
|
|
486
490
|
server: ns,
|
|
487
491
|
port: @port,
|
|
488
492
|
dnssec: @dnssec,
|
|
@@ -497,10 +501,22 @@ module Dnsruby
|
|
|
497
501
|
src_address6: @src_address6,
|
|
498
502
|
src_port: @src_port,
|
|
499
503
|
recurse: @recurse,
|
|
500
|
-
udp_size: @udp_size
|
|
501
|
-
|
|
504
|
+
udp_size: @udp_size,
|
|
505
|
+
ignore_config_resolv_errors: true})
|
|
502
506
|
end
|
|
503
|
-
|
|
507
|
+
end
|
|
508
|
+
|
|
509
|
+
new_resolvers = threads.map(&:value).compact
|
|
510
|
+
new_resolvers = new_resolvers.select do |resolver|
|
|
511
|
+
!resolver.nil? && !resolver.server.nil?
|
|
512
|
+
end
|
|
513
|
+
# if new_resolvers.empty?
|
|
514
|
+
# raise ArgumentError.new("No valid nameservers found in config")
|
|
515
|
+
# end
|
|
516
|
+
@single_res_mutex.synchronize { @single_resolvers.concat(new_resolvers) }
|
|
517
|
+
if @single_resolvers.nil? || @single_resolvers.empty?
|
|
518
|
+
raise ArgumentError.new("No valid nameservers found")
|
|
519
|
+
end
|
|
504
520
|
end
|
|
505
521
|
|
|
506
522
|
def set_config_nameserver(n)
|
|
@@ -888,6 +904,13 @@ module Dnsruby
|
|
|
888
904
|
return
|
|
889
905
|
end
|
|
890
906
|
|
|
907
|
+
# According to RFC 6891, a UDP payload size >512 bytes requires an
|
|
908
|
+
# EDNS OPT RR in the message.
|
|
909
|
+
if @parent.udp_size > 512 && !msg.get_opt
|
|
910
|
+
TheLog.debug("Automatically adding EDNS OPT RR for udp_size=#{ @parent.udp_size }")
|
|
911
|
+
msg.add_additional(Dnsruby::RR::OPT.new(@parent.udp_size))
|
|
912
|
+
end
|
|
913
|
+
|
|
891
914
|
begin
|
|
892
915
|
msg.encode
|
|
893
916
|
rescue EncodeError => err
|
data/lib/dnsruby/resource/CAA.rb
CHANGED
|
@@ -21,7 +21,7 @@ module Dnsruby
|
|
|
21
21
|
ClassValue = nil #:nodoc: all
|
|
22
22
|
TypeValue= Types::CAA #:nodoc: all
|
|
23
23
|
|
|
24
|
-
# The property tag for the record (issue|issuewild|iodef)
|
|
24
|
+
# The property tag for the record (issue|issuewild|issuemail|issuevmc|iodef|contactemail|contactphone)
|
|
25
25
|
attr_accessor :property_tag
|
|
26
26
|
# The value for the property_tag
|
|
27
27
|
attr_accessor :property_value
|
|
@@ -43,7 +43,10 @@ module Dnsruby
|
|
|
43
43
|
end
|
|
44
44
|
|
|
45
45
|
def from_string(input) #:nodoc: all
|
|
46
|
-
matches = (/(\d+) (issuewild|issue|iodef|contactemail|contactphone) "(.+)"$/).match(input)
|
|
46
|
+
matches = (/(\d+) (issuewild|issuemail|issuevmc|issue|iodef|contactemail|contactphone) "(.+)"$/i).match(input)
|
|
47
|
+
if matches.nil?
|
|
48
|
+
raise DecodeError.new("Cannot parse record: #{input[0...1000]}")
|
|
49
|
+
end
|
|
47
50
|
@flag = matches[1]
|
|
48
51
|
@property_tag = matches[2]
|
|
49
52
|
@property_value = matches[3]
|
|
@@ -383,7 +383,7 @@ module Dnsruby
|
|
|
383
383
|
]
|
|
384
384
|
)
|
|
385
385
|
|
|
386
|
-
|
|
386
|
+
OpenSSL::PKey::DSA.new(asn1.to_der)
|
|
387
387
|
end
|
|
388
388
|
|
|
389
389
|
# RFC6605, section 4
|
|
@@ -392,15 +392,22 @@ module Dnsruby
|
|
|
392
392
|
# uncompressed form of a curve point, "x | y".
|
|
393
393
|
def ec_key(curve = 'prime256v1')
|
|
394
394
|
group = OpenSSL::PKey::EC::Group.new(curve)
|
|
395
|
-
pkey = OpenSSL::PKey::EC.new(group)
|
|
396
395
|
# DNSSEC pub does not have first octet that determines whether it's uncompressed
|
|
397
396
|
# or compressed form, but it's required by OpenSSL to parse EC point correctly
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
397
|
+
dnskey_bn = OpenSSL::BN.new("\x04" + @key, 2)
|
|
398
|
+
key_point = OpenSSL::PKey::EC::Point.new(group, dnskey_bn)
|
|
399
|
+
|
|
400
|
+
asn1 = OpenSSL::ASN1::Sequence.new(
|
|
401
|
+
[
|
|
402
|
+
OpenSSL::ASN1::Sequence.new([
|
|
403
|
+
OpenSSL::ASN1::ObjectId.new("id-ecPublicKey"),
|
|
404
|
+
OpenSSL::ASN1::ObjectId.new(group.curve_name)
|
|
405
|
+
]),
|
|
406
|
+
OpenSSL::ASN1::BitString.new(key_point.to_octet_string(:uncompressed))
|
|
407
|
+
]
|
|
408
|
+
)
|
|
409
|
+
OpenSSL::PKey::EC.new(asn1.to_der)
|
|
403
410
|
end
|
|
404
411
|
end
|
|
405
412
|
end
|
|
406
|
-
end
|
|
413
|
+
end
|
data/lib/dnsruby/resource/IN.rb
CHANGED
|
@@ -87,13 +87,13 @@ module Dnsruby
|
|
|
87
87
|
|
|
88
88
|
def encode_rdata(msg, canonical=false) #:nodoc: all
|
|
89
89
|
msg.put_bytes(@address.address)
|
|
90
|
-
msg.put_pack("
|
|
90
|
+
msg.put_pack("C", @protocol)
|
|
91
91
|
msg.put_bytes(@bitmap)
|
|
92
92
|
end
|
|
93
93
|
|
|
94
94
|
def self.decode_rdata(msg) #:nodoc: all
|
|
95
95
|
address = IPv4.new(msg.get_bytes(4))
|
|
96
|
-
protocol, = msg.get_unpack("
|
|
96
|
+
protocol, = msg.get_unpack("C")
|
|
97
97
|
bitmap = msg.get_bytes
|
|
98
98
|
return self.new(address, protocol, bitmap)
|
|
99
99
|
end
|