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
|
@@ -152,7 +152,7 @@ module Dnsruby
|
|
|
152
152
|
end
|
|
153
153
|
|
|
154
154
|
def self.encode_types(nsec)
|
|
155
|
-
output = ''
|
|
155
|
+
output = +''
|
|
156
156
|
# types represents all 65536 possible RR types.
|
|
157
157
|
# Split up types into sets of 256 different types.
|
|
158
158
|
type_codes = []
|
|
@@ -171,7 +171,7 @@ module Dnsruby
|
|
|
171
171
|
|
|
172
172
|
unless types_to_go.empty?
|
|
173
173
|
# Then create the bitmap for them
|
|
174
|
-
bitmap = ''
|
|
174
|
+
bitmap = +''
|
|
175
175
|
# keep on adding them until there's none left
|
|
176
176
|
pos = 0
|
|
177
177
|
bitmap_pos = 0
|
data/lib/dnsruby/resource/NXT.rb
CHANGED
|
@@ -95,7 +95,7 @@ class NXT < RR
|
|
|
95
95
|
next_domain = Name.create(next_domain) if next_domain.is_a?(String)
|
|
96
96
|
types = TypeBitmap.from_type_codes(types) if types.is_a?(Array)
|
|
97
97
|
|
|
98
|
-
binary_string = ''.
|
|
98
|
+
binary_string = ''.b
|
|
99
99
|
binary_string << next_domain.canonical
|
|
100
100
|
binary_string << BitMapping.reverse_binary_string_bits(types.to_binary_string)
|
|
101
101
|
binary_string
|
data/lib/dnsruby/resource/OPT.rb
CHANGED
|
@@ -227,13 +227,12 @@ module Dnsruby
|
|
|
227
227
|
if @options
|
|
228
228
|
@options.each do |opt|
|
|
229
229
|
if opt.code == EDNS_SUBNET_OPTION
|
|
230
|
-
ret = ret + "CLIENT-SUBNET: #{get_client_subnet(opt)}"
|
|
230
|
+
ret = ret + "CLIENT-SUBNET: #{get_client_subnet(opt)}\n"
|
|
231
231
|
else
|
|
232
|
-
ret = ret + "
|
|
232
|
+
ret = ret + "OPT=#{opt.code}: #{opt.data}\n"
|
|
233
233
|
end
|
|
234
234
|
end
|
|
235
235
|
end
|
|
236
|
-
ret = ret + "\n"
|
|
237
236
|
return ret
|
|
238
237
|
end
|
|
239
238
|
|
data/lib/dnsruby/resource/TXT.rb
CHANGED
|
@@ -63,7 +63,7 @@ module Dnsruby
|
|
|
63
63
|
unquoted = false
|
|
64
64
|
seen_strings = false
|
|
65
65
|
pos = 0
|
|
66
|
-
input.sub
|
|
66
|
+
input = input.sub(/^\s*\(\s*/, "")
|
|
67
67
|
input.sub!(/\s*\)\s*$/, "")
|
|
68
68
|
input.each_char {|c|
|
|
69
69
|
if (((c == "'") || (c == '"')) && (!in_escaped) && (!unquoted))
|
|
@@ -138,6 +138,10 @@ module Dnsruby
|
|
|
138
138
|
@@sockets << query_settings.socket
|
|
139
139
|
@@socket_is_persistent[query_settings.socket] = query_settings.is_persistent_socket
|
|
140
140
|
}
|
|
141
|
+
wake_up_select_thread
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def wake_up_select_thread
|
|
141
145
|
begin
|
|
142
146
|
@@wakeup_sockets[0].send("wakeup!", 0)
|
|
143
147
|
rescue Exception
|
|
@@ -224,17 +228,20 @@ module Dnsruby
|
|
|
224
228
|
if (unused_loop_count > 10 && @@query_hash.empty? && @@observers.empty?)
|
|
225
229
|
Dnsruby.log.debug("Try stop select loop")
|
|
226
230
|
|
|
231
|
+
# We leave the @@wakeup_sockets here, but remove everything else
|
|
227
232
|
non_persistent_sockets = @@sockets.select { |s| ! @@socket_is_persistent[s] }
|
|
228
233
|
non_persistent_sockets.each do |socket|
|
|
229
|
-
socket
|
|
230
|
-
|
|
234
|
+
if socket != @@wakeup_sockets[1]
|
|
235
|
+
socket.close rescue nil
|
|
236
|
+
@@sockets.delete(socket)
|
|
237
|
+
end
|
|
231
238
|
end
|
|
232
239
|
|
|
233
|
-
Dnsruby.log.debug("Deleted #{non_persistent_sockets.size} non-persistent sockets," +
|
|
234
|
-
" #{@@sockets.count} persistent sockets remain.")
|
|
240
|
+
Dnsruby.log.debug("Deleted #{non_persistent_sockets.size - 1} non-persistent sockets," +
|
|
241
|
+
" #{@@sockets.count - 1} persistent sockets remain.")
|
|
235
242
|
@@socket_hash.clear
|
|
236
243
|
|
|
237
|
-
if @@sockets.
|
|
244
|
+
if @@sockets.size == 1
|
|
238
245
|
Dnsruby.log.debug("Stopping select loop")
|
|
239
246
|
return
|
|
240
247
|
end
|
|
@@ -247,10 +254,11 @@ module Dnsruby
|
|
|
247
254
|
# Removes closed sockets from @@sockets, and returns an array containing 1
|
|
248
255
|
# exception for each closed socket contained in @@socket_hash.
|
|
249
256
|
def clean_up_closed_sockets
|
|
257
|
+
exceptions = []
|
|
250
258
|
@@mutex.synchronize do
|
|
251
259
|
closed_sockets_in_hash = @@sockets.select(&:closed?).select { |s| @@socket_hash[s] }
|
|
252
260
|
@@sockets.delete_if { | socket | socket.closed? }
|
|
253
|
-
closed_sockets_in_hash.each_with_object([]) do |socket,
|
|
261
|
+
closed_sockets_in_hash.each_with_object([]) do |socket, exception|
|
|
254
262
|
@@socket_hash[socket].each do | client_id |
|
|
255
263
|
exceptions << [SocketEofResolvError.new("TCP socket closed before all answers received"), socket, client_id]
|
|
256
264
|
end
|
|
@@ -368,21 +376,28 @@ module Dnsruby
|
|
|
368
376
|
end
|
|
369
377
|
|
|
370
378
|
def remove_id(id)
|
|
371
|
-
|
|
372
379
|
@@mutex.synchronize do
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
380
|
+
remove_id_from_mutex_synchronized_block(id)
|
|
381
|
+
end
|
|
382
|
+
end
|
|
383
|
+
|
|
384
|
+
# THIS MUST BE CALLED FROM INSIDE A @@mutex SYNCHRONISED BLOCK!
|
|
385
|
+
def remove_id_from_mutex_synchronized_block(id)
|
|
386
|
+
socket = @@query_hash[id].socket
|
|
387
|
+
@@timeouts.delete(id)
|
|
388
|
+
@@query_hash.delete(id)
|
|
389
|
+
@@socket_hash[socket].delete(id)
|
|
390
|
+
|
|
391
|
+
decrement_remaining_queries(socket) if persistent?(socket)
|
|
392
|
+
|
|
393
|
+
if !persistent?(socket) || max_attained?(socket)
|
|
394
|
+
@@sockets.delete(socket)
|
|
395
|
+
@@socket_hash.delete(socket)
|
|
396
|
+
@@socket_remaining_queries.delete(socket)
|
|
397
|
+
@@socket_is_persistent.delete(socket)
|
|
398
|
+
@@tcp_buffers.delete(socket)
|
|
399
|
+
Dnsruby.log.debug("Closing socket #{socket}")
|
|
400
|
+
socket.close rescue nil
|
|
386
401
|
end
|
|
387
402
|
end
|
|
388
403
|
|
|
@@ -414,12 +429,12 @@ module Dnsruby
|
|
|
414
429
|
# Keep buffer for all TCP sockets, and return
|
|
415
430
|
# to select after reading available data. Once all data has been received,
|
|
416
431
|
# then process message.
|
|
417
|
-
buf=""
|
|
432
|
+
buf = +""
|
|
418
433
|
expected_length = 0
|
|
419
434
|
@@mutex.synchronize {
|
|
420
435
|
buf, expected_length = @@tcp_buffers[socket]
|
|
421
436
|
if (!buf)
|
|
422
|
-
buf = ""
|
|
437
|
+
buf = +""
|
|
423
438
|
expected_length = 2
|
|
424
439
|
@@tcp_buffers[socket]=[buf, expected_length]
|
|
425
440
|
end
|
|
@@ -443,7 +458,7 @@ module Dnsruby
|
|
|
443
458
|
|
|
444
459
|
return false
|
|
445
460
|
end
|
|
446
|
-
buf << input
|
|
461
|
+
buf << input if input
|
|
447
462
|
rescue
|
|
448
463
|
# Oh well - better luck next time!
|
|
449
464
|
return false
|
|
@@ -455,7 +470,7 @@ module Dnsruby
|
|
|
455
470
|
# We just read the data_length field. Now we need to start reading that many bytes.
|
|
456
471
|
@@mutex.synchronize {
|
|
457
472
|
answersize = buf.unpack('n')[0]
|
|
458
|
-
@@tcp_buffers[socket] = ["", answersize]
|
|
473
|
+
@@tcp_buffers[socket] = [+"", answersize]
|
|
459
474
|
}
|
|
460
475
|
return tcp_read(socket)
|
|
461
476
|
else
|
|
@@ -546,12 +561,10 @@ module Dnsruby
|
|
|
546
561
|
query_header_id = @@query_hash[id].query.header.id
|
|
547
562
|
if (query_header_id == e.partial_message.header.id)
|
|
548
563
|
# process the response
|
|
549
|
-
client_queue = nil
|
|
550
|
-
res = nil
|
|
551
|
-
query=nil
|
|
552
564
|
client_queue = @@query_hash[id].client_queue
|
|
553
565
|
res = @@query_hash[id].single_resolver
|
|
554
566
|
query = @@query_hash[id].query
|
|
567
|
+
remove_id_from_mutex_synchronized_block(id)
|
|
555
568
|
|
|
556
569
|
# NOW RESEND OVER TCP!
|
|
557
570
|
Thread.new {
|
|
@@ -641,6 +654,7 @@ module Dnsruby
|
|
|
641
654
|
do_select
|
|
642
655
|
}
|
|
643
656
|
end
|
|
657
|
+
wake_up_select_thread
|
|
644
658
|
end
|
|
645
659
|
|
|
646
660
|
def push_response_to_select(client_id, client_queue, msg, query, res)
|
|
@@ -661,6 +675,7 @@ module Dnsruby
|
|
|
661
675
|
do_select
|
|
662
676
|
}
|
|
663
677
|
end
|
|
678
|
+
wake_up_select_thread
|
|
664
679
|
end
|
|
665
680
|
|
|
666
681
|
def push_validation_response_to_select(client_id, client_queue, msg, err, query, res)
|
|
@@ -677,6 +692,7 @@ module Dnsruby
|
|
|
677
692
|
do_select
|
|
678
693
|
}
|
|
679
694
|
end
|
|
695
|
+
wake_up_select_thread
|
|
680
696
|
end
|
|
681
697
|
|
|
682
698
|
def send_queued_exceptions
|
data/lib/dnsruby/version.rb
CHANGED
data/test/spec_helper.rb
CHANGED
|
@@ -5,8 +5,12 @@ if Warning.respond_to?(:[]=)
|
|
|
5
5
|
end
|
|
6
6
|
|
|
7
7
|
if ENV['RUN_EXTRA_TASK'] == 'TRUE'
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
unless "test".frozen?
|
|
9
|
+
# Coverall setup term-ansi-color which isn't yet frozen string literal compatible
|
|
10
|
+
# Ref: https://github.com/flori/term-ansicolor/pull/38
|
|
11
|
+
require 'coveralls'
|
|
12
|
+
Coveralls.wear!
|
|
13
|
+
end
|
|
10
14
|
|
|
11
15
|
require 'simplecov'
|
|
12
16
|
|
|
@@ -22,7 +26,7 @@ require 'minitest'
|
|
|
22
26
|
require 'minitest/autorun'
|
|
23
27
|
require 'minitest/display'
|
|
24
28
|
|
|
25
|
-
|
|
29
|
+
Minitest::Display.options = {
|
|
26
30
|
suite_names: true,
|
|
27
31
|
color: true,
|
|
28
32
|
print: {
|
|
@@ -39,3 +43,18 @@ MiniTest::Display.options = {
|
|
|
39
43
|
require_relative '../lib/dnsruby'
|
|
40
44
|
require_relative 'test_utils'
|
|
41
45
|
end.()
|
|
46
|
+
|
|
47
|
+
def with_retries(max_attempts: 5, exceptions: [Dnsruby::ServFail, Dnsruby::ResolvTimeout], success_check: ->(result) { result }, &block)
|
|
48
|
+
attempts = 0
|
|
49
|
+
while attempts < max_attempts
|
|
50
|
+
begin
|
|
51
|
+
result = block.call
|
|
52
|
+
return result if success_check.call(result) # e.g., for nil-check: ->(r) { r }
|
|
53
|
+
rescue *exceptions => e
|
|
54
|
+
puts "Retry #{attempts + 1}/#{max_attempts}: #{e.class} - #{e.message}" if ENV['DEBUG_TESTS']
|
|
55
|
+
end
|
|
56
|
+
sleep(1)
|
|
57
|
+
attempts += 1
|
|
58
|
+
end
|
|
59
|
+
raise Minitest::Assertion, "Failed after #{max_attempts} retries"
|
|
60
|
+
end
|
data/test/tc_caa.rb
CHANGED
|
@@ -25,6 +25,8 @@ class TestCAA < Minitest::Test
|
|
|
25
25
|
{'foo.com. IN CAA 0 issue "ca.example.net"' => [0, 'issue', 'ca.example.net'],
|
|
26
26
|
'foo.com. IN CAA 1 issue "ca.example.net"' => [1, 'issue', 'ca.example.net'],
|
|
27
27
|
'foo.com. IN CAA 0 issuewild "ca.example.net"' => [0, 'issuewild', 'ca.example.net'],
|
|
28
|
+
'foo.com. IN CAA 0 issuemail "ca.example.net"' => [0, 'issuemail', 'ca.example.net'],
|
|
29
|
+
'foo.com. IN CAA 0 issuevmc "ca.example.net"' => [0, 'issuevmc', 'ca.example.net'],
|
|
28
30
|
'foo.com. IN CAA 0 iodef "mailto:security@example.com"' => [0, 'iodef', 'mailto:security@example.com'],
|
|
29
31
|
'foo.com. IN CAA 0 issue "ca.example.net; account=230123"' => [0, 'issue', 'ca.example.net; account=230123']
|
|
30
32
|
}.each do |text, data|
|
|
@@ -44,5 +46,16 @@ class TestCAA < Minitest::Test
|
|
|
44
46
|
end
|
|
45
47
|
end
|
|
46
48
|
|
|
49
|
+
def test_caa_error
|
|
50
|
+
{
|
|
51
|
+
'foo.com. IN CAA 0 ca.example.net "issue"' => [0, 'ca.example.net', 'issue'],
|
|
52
|
+
'foo.com. IN CAA 0 Issue "ca.example.net"' => [0, 'Issue', 'ca.example.net']
|
|
53
|
+
}.each do |text, data|
|
|
54
|
+
assert_raises DecodeError do
|
|
55
|
+
RR.create(text)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
47
60
|
end
|
|
48
61
|
|
data/test/tc_dns.rb
CHANGED
|
@@ -25,7 +25,7 @@ class TestDNS < Minitest::Test
|
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
def test_ipv4_address
|
|
28
|
-
Dnsruby::DNS.open { |dns| dns.getnames(Dnsruby::IPv4.create("
|
|
28
|
+
Dnsruby::DNS.open { |dns| dns.getnames(Dnsruby::IPv4.create("8.8.8.8")) }
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
# def test_resolv_rb_api
|
|
@@ -167,9 +167,9 @@ class TestDNS < Minitest::Test
|
|
|
167
167
|
end # test_online
|
|
168
168
|
|
|
169
169
|
def test_search_query_reverse
|
|
170
|
-
#
|
|
170
|
+
#
|
|
171
171
|
# test that getname() DTRT with reverse lookups
|
|
172
|
-
#
|
|
172
|
+
#
|
|
173
173
|
tests = [
|
|
174
174
|
{
|
|
175
175
|
:ip => '198.41.0.4',
|
|
@@ -183,7 +183,7 @@ class TestDNS < Minitest::Test
|
|
|
183
183
|
|
|
184
184
|
res = DNS.new
|
|
185
185
|
tests.each do |test|
|
|
186
|
-
name = res.getname(test[:ip])
|
|
186
|
+
name = with_retries { res.getname(test[:ip]) }
|
|
187
187
|
|
|
188
188
|
assert_instance_of(Name,name)
|
|
189
189
|
|
|
@@ -235,7 +235,7 @@ class TestDNS < Minitest::Test
|
|
|
235
235
|
res.config.apply_search_list=true
|
|
236
236
|
end
|
|
237
237
|
|
|
238
|
-
ans,
|
|
238
|
+
ans, _ = res.send_query(test[:name])
|
|
239
239
|
|
|
240
240
|
assert_instance_of(Message, ans)
|
|
241
241
|
|
|
@@ -249,14 +249,14 @@ class TestDNS < Minitest::Test
|
|
|
249
249
|
end
|
|
250
250
|
end
|
|
251
251
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
252
|
+
def test_port
|
|
253
|
+
d = DNS.new({:port => 5353})
|
|
254
|
+
assert(d.to_s.include?"5353")
|
|
255
|
+
end
|
|
256
256
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
257
|
+
def test_port_nil
|
|
258
|
+
d = DNS.new({:port => nil})
|
|
259
|
+
assert(d.to_s.include? Dnsruby::Config::DEFAULT_PORT.to_s)
|
|
260
|
+
end
|
|
261
261
|
|
|
262
262
|
end
|
data/test/tc_ecdsa.rb
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
require_relative 'spec_helper'
|
|
2
|
+
|
|
3
|
+
Dnsruby::TheLog.level = Logger::DEBUG
|
|
4
|
+
|
|
5
|
+
class VerifierTest < Minitest::Test
|
|
6
|
+
|
|
7
|
+
def test_ecdsa
|
|
8
|
+
inner_resolver = Dnsruby::Resolver.new
|
|
9
|
+
inner_resolver.do_validation = true
|
|
10
|
+
inner_resolver.dnssec = true
|
|
11
|
+
resolver = Dnsruby::Recursor.new(inner_resolver)
|
|
12
|
+
resolver.dnssec = true
|
|
13
|
+
|
|
14
|
+
# Dnsruby::TheLog.level=Logger::DEBUG
|
|
15
|
+
|
|
16
|
+
name = 'carlgo11.com'
|
|
17
|
+
type = 'A'
|
|
18
|
+
klass = 'IN'
|
|
19
|
+
|
|
20
|
+
begin
|
|
21
|
+
answer = resolver.query(name, type, klass)
|
|
22
|
+
print answer
|
|
23
|
+
rescue Exception => e
|
|
24
|
+
fatal_error("query failed: #{e}")
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
data/test/tc_escapedchars.rb
CHANGED
|
@@ -350,7 +350,7 @@ d0
|
|
|
350
350
|
packet = Message.decode(packetdata)
|
|
351
351
|
assert_equal( '\\\\e.eg.secret-wg.org',(packet.answer)[0].name.to_s,"Correctly dealt escaped backslash from wireformat \\\..eg.secret-wg.org")
|
|
352
352
|
|
|
353
|
-
|
|
353
|
+
RR.create(
|
|
354
354
|
:name => '\\e.eg.secret-wg.org',
|
|
355
355
|
:type => 'TXT',
|
|
356
356
|
:txtdata => '"WildCard Match"',
|
|
@@ -360,7 +360,6 @@ d0
|
|
|
360
360
|
|
|
361
361
|
|
|
362
362
|
|
|
363
|
-
klass = "IN"
|
|
364
363
|
ttl = 43200
|
|
365
364
|
name = 'def0au<.example.com'
|
|
366
365
|
|
|
@@ -471,17 +470,17 @@ d0
|
|
|
471
470
|
type = data[:type]
|
|
472
471
|
# foreach my $meth (keys %{$data}) {
|
|
473
472
|
(data.keys.each do |meth|
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
473
|
+
if (meth == :type)
|
|
474
|
+
assert_equal(Types.new(data[meth]).to_s, rr.send(meth).to_s, "#{type} - #meth() correct")
|
|
475
|
+
else
|
|
476
|
+
assert_equal(data[meth].to_s, rr.send(meth).to_s, "#{type} - #meth() correct")
|
|
477
|
+
end
|
|
479
478
|
end)
|
|
480
479
|
|
|
481
480
|
rr2 = RR.new_from_string(rr.to_s)
|
|
482
481
|
assert_equal(rr.to_s, rr2.to_s, "#{type} - Parsing from string works")
|
|
483
|
-
|
|
482
|
+
end
|
|
484
483
|
|
|
485
484
|
Name::Label.set_max_length(Name::Label::MaxLabelLength)
|
|
486
|
-
end
|
|
487
485
|
end
|
|
486
|
+
end
|
data/test/tc_gpos.rb
CHANGED
|
@@ -93,7 +93,7 @@ class TestGPOS < Minitest::Test
|
|
|
93
93
|
response_binary = "E0\x84\x80\x00\x01\x00\x01\x00\x01\x00\x01\x01a\adnsruby\x03com\x00\x00\e\x00\x01\xC0\f\x00\e\x00\x01\x00\x00*0\x00\x0F\x0410.0\x0420.0\x0430.0\xC0\x0E\x00\x02\x00\x01\x00\x00*0\x00\x06\x03ns1\xC0\x0E\xC0F\x00\x01\x00\x01\x00\x00*0\x00\x04\x7F\x00\x00\x01"
|
|
94
94
|
message_object = Message.decode(response_binary)
|
|
95
95
|
reconstructed_binary = message_object.encode
|
|
96
|
-
assert_equal response_binary.
|
|
96
|
+
assert_equal response_binary.b, reconstructed_binary
|
|
97
97
|
end
|
|
98
98
|
end
|
|
99
99
|
|
data/test/tc_hs.rb
CHANGED
|
@@ -2,11 +2,6 @@ require_relative 'spec_helper'
|
|
|
2
2
|
|
|
3
3
|
class TestDNS < Minitest::Test
|
|
4
4
|
|
|
5
|
-
def setup
|
|
6
|
-
Dnsruby::Config.reset
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
|
|
10
5
|
# Illustrates that when a message whose class is 'HS' is sent to
|
|
11
6
|
# a DNS server that does not support the HS class, using send_plain_message,
|
|
12
7
|
# the response returns with an rcode of NOTIMP and a Dnsruby::NotImp error.
|
data/test/tc_message.rb
CHANGED
|
@@ -49,7 +49,7 @@ class TestMessage < Minitest::Test
|
|
|
49
49
|
def test_rd_flag_displayed_when_true
|
|
50
50
|
message = sample_message
|
|
51
51
|
message.header.instance_variable_set(:@rd, true)
|
|
52
|
-
assert
|
|
52
|
+
assert(/;; flags(.+)rd/.match(message.to_s), message)
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
def test_header_line_contains_opcode_and_status_and_id
|
|
@@ -86,7 +86,7 @@ class TestMessage < Minitest::Test
|
|
|
86
86
|
end
|
|
87
87
|
|
|
88
88
|
def test_equals
|
|
89
|
-
response_as_string = "\x10\a\x81\x90\x00\x01\x00\x04\x00\x00\x00\x06\x03cnn\x03com\x00\x00\x02\x00\x01\xC0\f\x00\x02\x00\x01\x00\x01QC\x00\x14\x03ns3\ntimewarner\x03net\x00\xC0\f\x00\x02\x00\x01\x00\x01QC\x00\x11\x03ns2\x03p42\x06dynect\xC04\xC0\f\x00\x02\x00\x01\x00\x01QC\x00\x06\x03ns1\xC0)\xC0\f\x00\x02\x00\x01\x00\x01QC\x00\x06\x03ns1\xC0I\xC0%\x00\x01\x00\x01\x00\x001\xA2\x00\x04\xC7\aD\xEE\xC0E\x00\x01\x00\x01\x00\x00\xB1\x0E\x00\x04\xCC\r\xFA*\xC0b\x00\x01\x00\x01\x00\x009`\x00\x04\xCCJl\xEE\xC0t\x00\x01\x00\x01\x00\x00\xBDg\x00\x04\xD0NF*\xC0t\x00\x1C\x00\x01\x00\x00\x00\xBB\x00\x10 \x01\x05\x00\x00\x90\x00\x01\x00\x00\x00\x00\x00\x00\x00B\x00\x00)\x0F\xA0\x00\x00\x80\x00\x00\x00".
|
|
89
|
+
response_as_string = "\x10\a\x81\x90\x00\x01\x00\x04\x00\x00\x00\x06\x03cnn\x03com\x00\x00\x02\x00\x01\xC0\f\x00\x02\x00\x01\x00\x01QC\x00\x14\x03ns3\ntimewarner\x03net\x00\xC0\f\x00\x02\x00\x01\x00\x01QC\x00\x11\x03ns2\x03p42\x06dynect\xC04\xC0\f\x00\x02\x00\x01\x00\x01QC\x00\x06\x03ns1\xC0)\xC0\f\x00\x02\x00\x01\x00\x01QC\x00\x06\x03ns1\xC0I\xC0%\x00\x01\x00\x01\x00\x001\xA2\x00\x04\xC7\aD\xEE\xC0E\x00\x01\x00\x01\x00\x00\xB1\x0E\x00\x04\xCC\r\xFA*\xC0b\x00\x01\x00\x01\x00\x009`\x00\x04\xCCJl\xEE\xC0t\x00\x01\x00\x01\x00\x00\xBDg\x00\x04\xD0NF*\xC0t\x00\x1C\x00\x01\x00\x00\x00\xBB\x00\x10 \x01\x05\x00\x00\x90\x00\x01\x00\x00\x00\x00\x00\x00\x00B\x00\x00)\x0F\xA0\x00\x00\x80\x00\x00\x00".b
|
|
90
90
|
message = Message.decode(response_as_string)
|
|
91
91
|
assert(message == message, message.to_s)
|
|
92
92
|
end
|
data/test/tc_name.rb
CHANGED
|
@@ -24,7 +24,7 @@ class TestName < Minitest::Test
|
|
|
24
24
|
Name::Label.set_max_length(Name::Label::MaxLabelLength) # Other tests may have changed this
|
|
25
25
|
# Test max label length = 63
|
|
26
26
|
begin
|
|
27
|
-
|
|
27
|
+
Name.create("a.b.12345678901234567890123456789012345678901234567890123456789012345.com")
|
|
28
28
|
assert(false, "Label of more than max=63 allowed")
|
|
29
29
|
rescue ResolvError
|
|
30
30
|
end
|
|
@@ -33,7 +33,7 @@ class TestName < Minitest::Test
|
|
|
33
33
|
def test_name_length
|
|
34
34
|
# Test max name length=255
|
|
35
35
|
begin
|
|
36
|
-
|
|
36
|
+
Name.create("1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123.com")
|
|
37
37
|
assert(false, "Name of length > 255 allowed")
|
|
38
38
|
rescue ResolvError
|
|
39
39
|
end
|
data/test/tc_nxt.rb
CHANGED
|
@@ -60,7 +60,6 @@ class TestNXT < Minitest::Test
|
|
|
60
60
|
def test_binary_string_to_codes
|
|
61
61
|
test_type_codes_as_code_array = [1, 6, 28, 100]
|
|
62
62
|
test_type_codes_as_name_array = %w(A SOA AAAA UINFO)
|
|
63
|
-
test_type_codes_as_number = 1267650600228229401496971640898 # (2 ** 1) + (2 ** 6) + (2 ** 28) + (2 ** 100)
|
|
64
63
|
test_type_codes_as_binary_string = "\x10\x0\x0\x0\x0\x0\x0\x0\x0\x10\x0\x0\x42"
|
|
65
64
|
assert_equal(test_type_codes_as_code_array, RR::NXT::NxtTypes.binary_string_to_codes(test_type_codes_as_binary_string))
|
|
66
65
|
assert_equal(test_type_codes_as_name_array, RR::NXT::NxtTypes.binary_string_to_names(test_type_codes_as_binary_string))
|
data/test/tc_recur.rb
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# --
|
|
2
2
|
# Copyright 2007 Nominet UK
|
|
3
|
-
#
|
|
3
|
+
#
|
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
5
|
# you may not use this file except in compliance with the License.
|
|
6
6
|
# You may obtain a copy of the License at
|
|
7
|
-
#
|
|
7
|
+
#
|
|
8
8
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
#
|
|
9
|
+
#
|
|
10
10
|
# Unless required by applicable law or agreed to in writing, software
|
|
11
11
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
12
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
@@ -20,10 +20,7 @@ class TestRecur < Minitest::Test
|
|
|
20
20
|
def test_recur
|
|
21
21
|
Dnsruby::PacketSender.clear_caches
|
|
22
22
|
r = Dnsruby::Recursor.new
|
|
23
|
-
|
|
24
|
-
ret = r.query("uk", Dnsruby::Types.DNSKEY)
|
|
25
|
-
# print ret
|
|
26
|
-
assert ret, "Query result was nil."
|
|
23
|
+
ret = with_retries(max_attempts: 10, exceptions: [Dnsruby::ResolvError]) { r.query("uk", Dnsruby::Types.DNSKEY) }
|
|
27
24
|
assert ret.answer.length > 0, "Answer length should > 0, but was #{ret.answer.length}."
|
|
28
25
|
# ret = r.query_dorecursion("aaa.bigzone.uk-dnssec.nic.uk", Dnsruby::Types.DNSKEY)
|
|
29
26
|
# ret = r.query_dorecursion("uk-dnssec.nic.uk", Dnsruby::Types.DNSKEY)
|
data/test/tc_res_config.rb
CHANGED
|
@@ -92,4 +92,33 @@ class TestResolverConfig < Minitest::Test
|
|
|
92
92
|
end;
|
|
93
93
|
end
|
|
94
94
|
|
|
95
|
+
def test_bad_ns
|
|
96
|
+
begin
|
|
97
|
+
res = Dnsruby::Resolver.new(:nameserver => ["ns32.domiancontrol.com."])
|
|
98
|
+
res.query("example.com")
|
|
99
|
+
assert(false, "Should not query with bad nameserver")
|
|
100
|
+
rescue Exception => e
|
|
101
|
+
# OK
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def test_bad_ns_post_init
|
|
106
|
+
begin
|
|
107
|
+
resolver = Dnsruby::Resolver.new(recurse: false, do_caching: false, retry_times: 2)
|
|
108
|
+
resolver.nameserver = ["ns32.domiancontrol.com."]
|
|
109
|
+
assert(false, "Should not allow bad nameserver")
|
|
110
|
+
resolver.query("example.com")
|
|
111
|
+
rescue ArgumentError
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def test_one_good_ns_rest_bad
|
|
116
|
+
begin
|
|
117
|
+
resolver = Dnsruby::Resolver.new(recurse: false, do_caching: false, retry_times: 2)
|
|
118
|
+
resolver.nameserver = ["ns32.domiancontrol.com.", "1.1.1.1"]
|
|
119
|
+
resolver.query("example.com")
|
|
120
|
+
rescue ArgumentError
|
|
121
|
+
assert(false, "Should allow one good nameserver")
|
|
122
|
+
end
|
|
123
|
+
end
|
|
95
124
|
end
|
data/test/tc_resolv.rb
CHANGED
|
@@ -51,19 +51,26 @@ class TestResolv < Minitest::Test
|
|
|
51
51
|
end
|
|
52
52
|
end
|
|
53
53
|
|
|
54
|
-
|
|
55
54
|
def test_resolv_address_to_name
|
|
56
55
|
|
|
57
|
-
|
|
56
|
+
name = with_retries { Dnsruby::Resolv.getname(IPV4_ADDR) }
|
|
57
|
+
assert_equal(SHORT_ABSOLUTE_NAME, name.to_s(true))
|
|
58
58
|
|
|
59
59
|
assert_raises(Dnsruby::ResolvError) do
|
|
60
60
|
Dnsruby::Resolv.getname(SHORT_ABSOLUTE_NAME)
|
|
61
61
|
end
|
|
62
62
|
|
|
63
|
-
names = Dnsruby::Resolv.getnames(IPV4_ADDR)
|
|
63
|
+
names = with_retries { Dnsruby::Resolv.getnames(IPV4_ADDR) }
|
|
64
64
|
assert_equal(1, names.size)
|
|
65
65
|
assert_equal(SHORT_ABSOLUTE_NAME, names.first.to_s(true))
|
|
66
|
-
|
|
66
|
+
|
|
67
|
+
found_names = with_retries(success_check: ->(_) { true }) do
|
|
68
|
+
names = []
|
|
69
|
+
Dnsruby::Resolv.each_name(IPV4_ADDR) { |name| names << name }
|
|
70
|
+
names
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
assert_equal(SHORT_ABSOLUTE_NAME, found_names.first.to_s(true))
|
|
67
74
|
end
|
|
68
75
|
|
|
69
76
|
def test_resolv_address_to_address
|