Skip to content

Commit 267167b

Browse files
committed
http/client: Try multiple dns results when connecting
1 parent 4117d56 commit 267167b

File tree

1 file changed

+45
-19
lines changed

1 file changed

+45
-19
lines changed

http/client.lua

+45-19
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,10 @@ local function dns_lookup(records, dns_resolver, host, query_type, filter_type,
115115
end
116116
for rec in each_matching_record(packet, host, filter_type) do
117117
local t = rec:type()
118-
if t == cqueues_dns_record.AAAA or t == cqueues_dns_record.A then
119-
table.insert(records, rec)
118+
if t == cqueues_dns_record.AAAA then
119+
table.insert(records, { family = cs.AF_INET6, host = rec:addr() })
120+
elseif t == cqueues_dns_record.A then
121+
table.insert(records, { family = cs.AF_INET, host = rec:addr() })
120122
end
121123
end
122124
end
@@ -136,24 +138,26 @@ local function connect(options, timeout)
136138
end
137139
end
138140

141+
local deadline = timeout and monotime()+timeout
142+
139143
local host = options.host
140-
if not path and not http_util.is_ip(host) then
144+
local records
145+
if path then
146+
records = { { family = family, path = path } }
147+
elseif http_util.is_ip(host) then
148+
family = host:find(":", 1, true) and cs.AF_INET6 or cs.AF_INET
149+
records = { { family = family, host = host } }
150+
else
141151
local dns_resolver = options.dns_resolver or cqueues_dns.getpool()
142-
local deadline = timeout and monotime()+timeout
143-
local records = {}
144-
if family == nil or family == cs.AF_UNSPEC then
152+
records = {}
153+
if family == cs.AF_UNSPEC then
145154
dns_lookup(records, dns_resolver, host, cqueues_dns_record.AAAA, nil, timeout)
146155
dns_lookup(records, dns_resolver, host, cqueues_dns_record.A, nil, deadline and deadline-monotime())
147156
elseif family == cs.AF_INET then
148157
dns_lookup(records, dns_resolver, host, cqueues_dns_record.A, cqueues_dns_record.A, timeout)
149158
elseif family == cs.AF_INET6 then
150159
dns_lookup(records, dns_resolver, host, cqueues_dns_record.AAAA, cqueues_dns_record.AAAA, timeout)
151160
end
152-
local rec = records[1]
153-
if not rec then
154-
return nil, "The name does not resolve for the supplied parameters"
155-
end
156-
host = rec:addr()
157161
timeout = deadline and deadline-monotime()
158162
end
159163

@@ -176,20 +180,42 @@ local function connect(options, timeout)
176180
}
177181
end
178182

179-
local s, err, errno = ca.fileresult(cs.connect {
180-
family = family;
181-
host = host;
183+
local connect_params = {
184+
family = nil;
185+
host = nil;
182186
port = options.port;
183-
path = path;
187+
path = nil;
184188
bind = bind;
185189
sendname = false;
186190
v6only = options.v6only;
187191
nodelay = true;
188-
})
189-
if s == nil then
190-
return nil, err, errno
192+
}
193+
194+
local lasterr, lasterrno = "The name does not resolve for the supplied parameters"
195+
for _, rec in ipairs(records) do
196+
connect_params.family = rec.family;
197+
connect_params.host = rec.host;
198+
connect_params.path = rec.path;
199+
local s
200+
s, lasterr, lasterrno = ca.fileresult(cs.connect(connect_params))
201+
if s then
202+
local c
203+
c, lasterr, lasterrno = negotiate(s, options, timeout)
204+
if c then
205+
-- Force TCP connect to occur
206+
local ok
207+
ok, lasterr, lasterrno = c:connect(deadline and deadline-monotime())
208+
if ok then
209+
return c
210+
end
211+
c:close()
212+
else
213+
s:close()
214+
end
215+
timeout = deadline and deadline-monotime()
216+
end
191217
end
192-
return negotiate(s, options, timeout)
218+
return nil, lasterr, lasterrno
193219
end
194220

195221
return {

0 commit comments

Comments
 (0)