Skip to content

Commit f53cea1

Browse files
committed
add testcase
1 parent 7984602 commit f53cea1

File tree

1 file changed

+115
-1
lines changed

1 file changed

+115
-1
lines changed

test/resolv/test_dns.rb

Lines changed: 115 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -457,4 +457,118 @@ def dns.each_resource(name, typeclass)
457457
end
458458
assert_raise(Resolv::ResolvError) { dns.each_name('example.com') }
459459
end
460-
end
460+
461+
def test_query_ipv4_try_next_dns_if_first_answers_with_servfail
462+
begin
463+
OpenSSL
464+
rescue LoadError
465+
omit 'autoload problem. see [ruby-dev:45021][Bug #5786]'
466+
end if defined?(OpenSSL)
467+
468+
with_udp('127.0.0.1', 0) {|first|
469+
with_udp('127.0.0.1', 0) {|second|
470+
_, server_one_port, _, server_one_address = first.addr
471+
_, server_two_port, _, server_two_address = second.addr
472+
begin
473+
client_thread = Thread.new {
474+
Resolv::DNS.open(:nameserver_port => [[server_one_address, server_one_port], [server_two_address, server_two_port]]).getaddress("example.org")
475+
}
476+
server_one_thread = Thread.new {
477+
msg, (_, client_port, _, client_address) = Timeout.timeout(5) {first.recvfrom(4096)}
478+
id, flags, qdcount, ancount, nscount, arcount = msg.unpack("nnnnnn")
479+
480+
qr = (flags & 0x8000) >> 15
481+
opcode = (flags & 0x7800) >> 11
482+
aa = (flags & 0x0400) >> 10
483+
tc = (flags & 0x0200) >> 9
484+
rd = (flags & 0x0100) >> 8
485+
ra = (flags & 0x0080) >> 7
486+
z = (flags & 0x0070) >> 4
487+
rcode = flags & 0x000f
488+
_rest = msg[12..-1]
489+
questions = msg.bytes[12..-1]
490+
491+
id = id
492+
qr = 1
493+
opcode = opcode
494+
aa = 0
495+
tc = 0
496+
rd = rd
497+
ra = 1
498+
z = 0
499+
rcode = 2 # ServFail
500+
qdcount = 1
501+
ancount = 0
502+
nscount = 0
503+
arcount = 0
504+
word2 = (qr << 15) |
505+
(opcode << 11) |
506+
(aa << 10) |
507+
(tc << 9) |
508+
(rd << 8) |
509+
(ra << 7) |
510+
(z << 4) |
511+
rcode
512+
msg = [id, word2, qdcount, ancount, nscount, arcount].pack("nnnnnn")
513+
msg << questions.pack('c*')
514+
515+
first.send(msg, 0, client_address, client_port)
516+
}
517+
server_two_thread = Thread.new {
518+
msg, (_, client_port, _, client_address) = Timeout.timeout(5) {second.recvfrom(4096)}
519+
id, flags, qdcount, ancount, nscount, arcount = msg.unpack("nnnnnn")
520+
521+
qr = (flags & 0x8000) >> 15
522+
opcode = (flags & 0x7800) >> 11
523+
aa = (flags & 0x0400) >> 10
524+
tc = (flags & 0x0200) >> 9
525+
rd = (flags & 0x0100) >> 8
526+
ra = (flags & 0x0080) >> 7
527+
z = (flags & 0x0070) >> 4
528+
rcode = flags & 0x000f
529+
_rest = msg[12..-1]
530+
531+
questions = msg.bytes[12..-1]
532+
533+
id = id
534+
qr = 1
535+
opcode = opcode
536+
aa = 0
537+
tc = 0
538+
rd = rd
539+
ra = 1
540+
z = 0
541+
rcode = 0 # NoError
542+
qdcount = 1
543+
ancount = 1
544+
nscount = 0
545+
arcount = 0
546+
word2 = (qr << 15) |
547+
(opcode << 11) |
548+
(aa << 10) |
549+
(tc << 9) |
550+
(rd << 8) |
551+
(ra << 7) |
552+
(z << 4) |
553+
rcode
554+
msg = [id, word2, qdcount, ancount, nscount, arcount].pack("nnnnnn")
555+
msg << questions.pack('c*')
556+
type = 1
557+
klass = 1
558+
ttl = 3600
559+
rdlength = 4
560+
rdata = [52,0,2,1].pack("CCCC")
561+
rr = [0xc00c, type, klass, ttl, rdlength, rdata].pack("nnnNna*")
562+
msg << rr
563+
564+
second.send(msg, 0, client_address, client_port)
565+
}
566+
result, _, _ = assert_join_threads([client_thread, server_one_thread, server_two_thread])
567+
568+
assert_instance_of(Resolv::IPv4, result)
569+
assert_equal("52.0.2.1", result.to_s)
570+
end
571+
}
572+
}
573+
end
574+
end

0 commit comments

Comments
 (0)