ruby-changes:65773
From: usa <ko1@a...>
Date: Mon, 5 Apr 2021 08:48:09 +0900 (JST)
Subject: [ruby-changes:65773] bde8e4e6f8 (ruby_2_6): merge revision(s) 9682db065158da5fa4ec8a3bc267da45b429b92c: [Backport #17658]
https://git.ruby-lang.org/ruby.git/commit/?id=bde8e4e6f8 From bde8e4e6f89c579064f0af5a5d922444797478bc Mon Sep 17 00:00:00 2001 From: usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> Date: Sun, 4 Apr 2021 23:47:58 +0000 Subject: merge revision(s) 9682db065158da5fa4ec8a3bc267da45b429b92c: [Backport #17658] Remove sender/message_id pair after response received in resolv Once a response for a given DNS request has been received (which requires a matching message id), the [sender, message_id] pair should be removed from the list of valid senders. This makes it so duplicate responses from the same sender are ignored. Fixes [Bug #12838] --- lib/resolv.rb | 2 +- test/resolv/test_dns.rb | 113 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 114 insertions(+), 1 deletion(-) git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_6@67929 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- lib/resolv.rb | 2 +- test/resolv/test_dns.rb | 113 ++++++++++++++++++++++++++++++++++++++++++++++++ version.h | 2 +- 3 files changed, 115 insertions(+), 2 deletions(-) diff --git a/lib/resolv.rb b/lib/resolv.rb index edca926..93b57c6 100644 --- a/lib/resolv.rb +++ b/lib/resolv.rb @@ -701,7 +701,7 @@ class Resolv https://github.com/ruby/ruby/blob/trunk/lib/resolv.rb#L701 end def sender_for(addr, msg) - @senders[[addr,msg.id]] + @senders.delete([addr,msg.id]) end def close diff --git a/test/resolv/test_dns.rb b/test/resolv/test_dns.rb index 669d86b..c49c152 100644 --- a/test/resolv/test_dns.rb +++ b/test/resolv/test_dns.rb @@ -128,6 +128,119 @@ class TestResolvDNS < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/resolv/test_dns.rb#L128 } end + def test_query_ipv4_duplicate_responses + begin + OpenSSL + rescue LoadError + skip 'autoload problem. see [ruby-dev:45021][Bug #5786]' + end if defined?(OpenSSL) + + with_udp('127.0.0.1', 0) {|u| + _, server_port, _, server_address = u.addr + begin + client_thread = Thread.new { + Resolv::DNS.open(:nameserver_port => [[server_address, server_port]], :search => ['bad1.com', 'bad2.com', 'good.com'], ndots: 5) {|dns| + dns.getaddress("example") + } + } + server_thread = Thread.new { + 3.times do + msg, (_, client_port, _, client_address) = Timeout.timeout(5) {u.recvfrom(4096)} + id, flags, qdcount, ancount, nscount, arcount = msg.unpack("nnnnnn") + + qr = (flags & 0x8000) >> 15 + opcode = (flags & 0x7800) >> 11 + aa = (flags & 0x0400) >> 10 + tc = (flags & 0x0200) >> 9 + rd = (flags & 0x0100) >> 8 + ra = (flags & 0x0080) >> 7 + z = (flags & 0x0070) >> 4 + rcode = flags & 0x000f + rest = msg[12..-1] + + questions = msg.bytes[12..-1] + labels = [] + idx = 0 + while idx < questions.length-5 + size = questions[idx] + labels << questions[idx+1..idx+size].pack('c*') + idx += size+1 + end + hostname = labels.join('.') + + if hostname == "example.good.com" + id = id + qr = 1 + opcode = opcode + aa = 0 + tc = 0 + rd = rd + ra = 1 + z = 0 + rcode = 0 + qdcount = 1 + ancount = 1 + nscount = 0 + arcount = 0 + word2 = (qr << 15) | + (opcode << 11) | + (aa << 10) | + (tc << 9) | + (rd << 8) | + (ra << 7) | + (z << 4) | + rcode + msg = [id, word2, qdcount, ancount, nscount, arcount].pack("nnnnnn") + msg << questions.pack('c*') + type = 1 + klass = 1 + ttl = 3600 + rdlength = 4 + rdata = [52,0,2,1].pack("CCCC") + rr = [0xc00c, type, klass, ttl, rdlength, rdata].pack("nnnNna*") + msg << rr + rdata = [52,0,2,2].pack("CCCC") + rr = [0xc00c, type, klass, ttl, rdlength, rdata].pack("nnnNna*") + msg << rr + + u.send(msg, 0, client_address, client_port) + else + id = id + qr = 1 + opcode = opcode + aa = 0 + tc = 0 + rd = rd + ra = 1 + z = 0 + rcode = 3 + qdcount = 1 + ancount = 0 + nscount = 0 + arcount = 0 + word2 = (qr << 15) | + (opcode << 11) | + (aa << 10) | + (tc << 9) | + (rd << 8) | + (ra << 7) | + (z << 4) | + rcode + msg = [id, word2, qdcount, ancount, nscount, arcount].pack("nnnnnn") + msg << questions.pack('c*') + + u.send(msg, 0, client_address, client_port) + u.send(msg, 0, client_address, client_port) + end + end + } + result, _ = assert_join_threads([client_thread, server_thread]) + assert_instance_of(Resolv::IPv4, result) + assert_equal("52.0.2.1", result.to_s) + end + } + end + def test_query_ipv4_address_timeout with_udp('127.0.0.1', 0) {|u| _, port , _, host = u.addr diff --git a/version.h b/version.h index 6863146..a968829 100644 --- a/version.h +++ b/version.h @@ -1,6 +1,6 @@ https://github.com/ruby/ruby/blob/trunk/version.h#L1 #define RUBY_VERSION "2.6.7" #define RUBY_RELEASE_DATE "2021-04-05" -#define RUBY_PATCHLEVEL 188 +#define RUBY_PATCHLEVEL 189 #define RUBY_RELEASE_YEAR 2021 #define RUBY_RELEASE_MONTH 4 -- cgit v1.1 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/