Skip to content

Commit

Permalink
http/client: Try multiple dns results when connecting
Browse files Browse the repository at this point in the history
  • Loading branch information
daurnimator committed Aug 22, 2018
1 parent a8458ca commit fc40f35
Showing 1 changed file with 43 additions and 18 deletions.
61 changes: 43 additions & 18 deletions http/client.lua
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,10 @@ local function dns_lookup(dns_resolver, host, query_type, filter_type, records,
end
for rec in each_matching_record(packet, host, filter_type) do
local t = rec:type()
if t == cqueues_dns_record.AAAA or t == cqueues_dns_record.A then
table.insert(records, rec)
if t == cqueues_dns_record.AAAA then
table.insert(records, { family = cs.AF_INET6, host = rec:addr() })
elseif t == cqueues_dns_record.A then
table.insert(records, { family = cs.AF_INET, host = rec:addr() })
end
end
end
Expand Down Expand Up @@ -166,11 +168,17 @@ local function connect(options, timeout)
}
end

local deadline = timeout and monotime()+timeout

local host = options.host
if not path and not http_util.is_ip(host) then
local records
if path then
records = { { family = family, path = path } }
elseif http_util.is_ip(host) then
records = { { family = family, host = host } }
else
local dns_resolver = options.dns_resolver or cqueues_dns.getpool()
local deadline = timeout and monotime()+timeout
local records = {}
records = {}
if family == cs.AF_UNSPEC then
dns_lookup(dns_resolver, host, cqueues_dns_record.AAAA, nil, records, timeout)
dns_lookup(dns_resolver, host, cqueues_dns_record.A, nil, records, deadline and deadline-monotime())
Expand All @@ -179,28 +187,45 @@ local function connect(options, timeout)
elseif family == cs.AF_INET6 then
dns_lookup(dns_resolver, host, cqueues_dns_record.AAAA, cqueues_dns_record.AAAA, records, timeout)
end
local rec = records[1]
if not rec then
return nil, "The name does not resolve for the supplied parameters"
end
host = rec:addr()
timeout = deadline and deadline-monotime()
end

local s, err, errno = ca.fileresult(cs.connect {
family = family;
host = host;
local connect_params = {
family = nil;
host = nil;
port = options.port;
path = path;
path = nil;
bind = bind;
sendname = false;
v6only = options.v6only;
nodelay = true;
})
if s == nil then
return nil, err, errno
}

local lasterr, lasterrno = "The name does not resolve for the supplied parameters"
for _, rec in ipairs(records) do
connect_params.family = rec.family;
connect_params.host = rec.host;
connect_params.path = rec.path;
local s
s, lasterr, lasterrno = ca.fileresult(cs.connect(connect_params))
if s then
local c
c, lasterr, lasterrno = negotiate(s, options, timeout)
if c then
-- Force TCP connect to occur
local ok
ok, lasterr, lasterrno = c:connect(deadline and deadline-monotime())
if ok then
return c
end
c:close()
else
s:close()
end
timeout = deadline and deadline-monotime()
end
end
return negotiate(s, options, timeout)
return nil, lasterr, lasterrno
end

return {
Expand Down

0 comments on commit fc40f35

Please sign in to comment.