Open daurnimator opened 8 years ago
My above code is wrong: checking for name
like I did doesn't work if e.g. there is a CNAME pointing to somewhere else (and that's also included) e.g. checkip.dyndns.org:
;; [HEADER]
;; qid : 0
;; qr : QUERY(0)
;; opcode : QUERY(0)
;; aa : NON-AUTHORITATIVE(0)
;; tc : NOT-TRUNCATED(0)
;; rd : RECURSION-NOT-DESIRED(0)
;; ra : RECURSION-NOT-ALLOWED(0)
;; rcode : NOERROR(0)
;; [QUESTION:1]
;checkip.dyndns.org. IN A
;; [ANSWER:4]
checkip.dyndns.org. 197 IN CNAME checkip.dyndns.com.
checkip.dyndns.com. 481 IN A 216.146.38.70
checkip.dyndns.com. 481 IN A 216.146.43.70
checkip.dyndns.com. 481 IN A 91.198.22.70
What should the process be for getting the IP out of a response?
Another guess:
local host = name .. "."
for _=1,8 do -- avoid loops
for rec in res:grep{section = "answer", class = "IN", name = host} do
local t = rec:type()
if t == dns_record.A or t == dns_record.AAAA then
return rec:addr()
elseif t == dns_record.CNAME then
host = rec:host()
break
end
end
if host == nil then
break
end
end
return nil, "not found"
Working with @Habbie I wrote this:
-- `type` parameter is what sort of records you want to find could be "A" or
-- "AAAA" or `nil` if you want to filter yourself e.g. to implement
-- https://www.ietf.org/archive/id/draft-vavrusa-dnsop-aaaa-for-free-00.txt
local function each_matching_record(pkt, name, type)
-- First need to do CNAME chasing
local params = {
section = "answer";
class = cqueues_dns_record.IN;
type = cqueues_dns_record.CNAME;
name = name .. ".";
}
for _=1, 8 do -- avoid cname loops
-- Ignores any CNAME record past the first (which should never occur anyway)
local func, state, first = pkt:grep(params)
local record = func(state, first)
if record == nil then
-- Not found
break
end
params.name = record:host()
end
params.type = type
return pkt:grep(params)
end
It can be complex figuring out how to do a 'normal' dns query.
e.g. to lookup an ip for google.com, you currently need something like:
Add a simpler interface.