refactor of internal resolver cache lookup access to make it a bit safer

This commit is contained in:
HoneyryderChuck 2024-10-30 11:29:41 +00:00
parent a3246e506d
commit e32d226151
2 changed files with 26 additions and 15 deletions

View File

@ -53,8 +53,8 @@ module HTTPX
def cached_lookup(hostname)
now = Utils.now
@lookup_mutex.synchronize do
lookup(hostname, now)
lookup_synchronize do |lookups|
lookup(hostname, lookups, now)
end
end
@ -63,37 +63,37 @@ module HTTPX
entries.each do |entry|
entry["TTL"] += now
end
@lookup_mutex.synchronize do
lookup_synchronize do |lookups|
case family
when Socket::AF_INET6
@lookups[hostname].concat(entries)
lookups[hostname].concat(entries)
when Socket::AF_INET
@lookups[hostname].unshift(*entries)
lookups[hostname].unshift(*entries)
end
entries.each do |entry|
next unless entry["name"] != hostname
case family
when Socket::AF_INET6
@lookups[entry["name"]] << entry
lookups[entry["name"]] << entry
when Socket::AF_INET
@lookups[entry["name"]].unshift(entry)
lookups[entry["name"]].unshift(entry)
end
end
end
end
# do not use directly!
def lookup(hostname, ttl)
return unless @lookups.key?(hostname)
def lookup(hostname, lookups, ttl)
return unless lookups.key?(hostname)
entries = @lookups[hostname] = @lookups[hostname].select do |address|
entries = lookups[hostname] = lookups[hostname].select do |address|
address["TTL"] > ttl
end
ips = entries.flat_map do |address|
if address.key?("alias")
lookup(address["alias"], ttl)
lookup(address["alias"], lookups, ttl)
else
IPAddr.new(address["data"])
end
@ -103,12 +103,11 @@ module HTTPX
end
def generate_id
@identifier_mutex.synchronize { @identifier = (@identifier + 1) & 0xFFFF }
id_synchronize { @identifier = (@identifier + 1) & 0xFFFF }
end
def encode_dns_query(hostname, type: Resolv::DNS::Resource::IN::A, message_id: generate_id)
Resolv::DNS::Message.new.tap do |query|
query.id = message_id
Resolv::DNS::Message.new(message_id).tap do |query|
query.rd = 1
query.add_question(hostname, type)
end.encode
@ -150,5 +149,13 @@ module HTTPX
[:ok, addresses]
end
def lookup_synchronize
@lookup_mutex.synchronize { yield(@lookups) }
end
def id_synchronize(&block)
@identifier_mutex.synchronize(&block)
end
end
end

View File

@ -28,12 +28,16 @@ module HTTPX
def self?.cached_lookup_set: (String hostname, ip_family family, Array[dns_result] addresses) -> void
def self?.lookup: (String hostname, Numeric ttl) -> Array[IPAddr]?
def self?.lookup: (String hostname, Hash[String, Array[dns_result]] lookups, Numeric ttl) -> Array[IPAddr]?
def self?.generate_id: () -> Integer
def self?.encode_dns_query: (String hostname, ?type: dns_resource, ?message_id: Integer) -> String
def self?.decode_dns_answer: (String) -> dns_decoding_response
def self?.lookup_synchronize: [U] () { (Hash[String, Array[dns_result]] lookups) -> U } -> U
def self?.id_synchronize: () { () -> void } -> void
end
end