[前][次][番号順一覧][スレッド一覧]

ruby-changes:65570

From: nagachika <ko1@a...>
Date: Sat, 20 Mar 2021 13:18:57 +0900 (JST)
Subject: [ruby-changes:65570] 70c3a195f3 (ruby_2_7): merge revision(s) 9682db065158da5fa4ec8a3bc267da45b429b92c: [Backport #12838] [Backport #17658]

https://git.ruby-lang.org/ruby.git/commit/?id=70c3a195f3

From 70c3a195f39763dccdf9367d0c9b7e815431a41a Mon Sep 17 00:00:00 2001
From: nagachika <nagachika@r...>
Date: Sat, 20 Mar 2021 13:18:32 +0900
Subject: merge revision(s) 9682db065158da5fa4ec8a3bc267da45b429b92c: [Backport
 #12838] [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(-)
---
 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 e7b45e7..fd5e475 100644
--- a/lib/resolv.rb
+++ b/lib/resolv.rb
@@ -706,7 +706,7 @@ class Resolv https://github.com/ruby/ruby/blob/trunk/lib/resolv.rb#L706
       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 70d5067..617babf 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 ef9fcd0..a5bd5b5 100644
--- a/version.h
+++ b/version.h
@@ -2,7 +2,7 @@ https://github.com/ruby/ruby/blob/trunk/version.h#L2
 # define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR
 #define RUBY_VERSION_TEENY 3
 #define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR
-#define RUBY_PATCHLEVEL 163
+#define RUBY_PATCHLEVEL 164
 
 #define RUBY_RELEASE_YEAR 2021
 #define RUBY_RELEASE_MONTH 3
-- 
cgit v1.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]