mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
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]
This commit is contained in:
parent
5823f6c25b
commit
9682db0651
Notes:
git
2020-11-08 06:13:01 +09:00
2 changed files with 114 additions and 1 deletions
|
@ -706,7 +706,7 @@ class Resolv
|
||||||
end
|
end
|
||||||
|
|
||||||
def sender_for(addr, msg)
|
def sender_for(addr, msg)
|
||||||
@senders[[addr,msg.id]]
|
@senders.delete([addr,msg.id])
|
||||||
end
|
end
|
||||||
|
|
||||||
def close
|
def close
|
||||||
|
|
|
@ -128,6 +128,119 @@ class TestResolvDNS < Test::Unit::TestCase
|
||||||
}
|
}
|
||||||
end
|
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
|
def test_query_ipv4_address_timeout
|
||||||
with_udp('127.0.0.1', 0) {|u|
|
with_udp('127.0.0.1', 0) {|u|
|
||||||
_, port , _, host = u.addr
|
_, port , _, host = u.addr
|
||||||
|
|
Loading…
Add table
Reference in a new issue