Skip to content

Commit fc40f35

Browse files
committed
http/client: Try multiple dns results when connecting
1 parent a8458ca commit fc40f35

File tree

1 file changed

+43
-18
lines changed

1 file changed

+43
-18
lines changed

http/client.lua

+43-18
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,10 @@ local function dns_lookup(dns_resolver, host, query_type, filter_type, records,
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
@@ -166,11 +168,17 @@ local function connect(options, timeout)
166168
}
167169
end
168170

171+
local deadline = timeout and monotime()+timeout
172+
169173
local host = options.host
170-
if not path and not http_util.is_ip(host) then
174+
local records
175+
if path then
176+
records = { { family = family, path = path } }
177+
elseif http_util.is_ip(host) then
178+
records = { { family = family, host = host } }
179+
else
171180
local dns_resolver = options.dns_resolver or cqueues_dns.getpool()
172-
local deadline = timeout and monotime()+timeout
173-
local records = {}
181+
records = {}
174182
if family == cs.AF_UNSPEC then
175183
dns_lookup(dns_resolver, host, cqueues_dns_record.AAAA, nil, records, timeout)
176184
dns_lookup(dns_resolver, host, cqueues_dns_record.A, nil, records, deadline and deadline-monotime())
@@ -179,28 +187,45 @@ local function connect(options, timeout)
179187
elseif family == cs.AF_INET6 then
180188
dns_lookup(dns_resolver, host, cqueues_dns_record.AAAA, cqueues_dns_record.AAAA, records, timeout)
181189
end
182-
local rec = records[1]
183-
if not rec then
184-
return nil, "The name does not resolve for the supplied parameters"
185-
end
186-
host = rec:addr()
187190
timeout = deadline and deadline-monotime()
188191
end
189192

190-
local s, err, errno = ca.fileresult(cs.connect {
191-
family = family;
192-
host = host;
193+
local connect_params = {
194+
family = nil;
195+
host = nil;
193196
port = options.port;
194-
path = path;
197+
path = nil;
195198
bind = bind;
196199
sendname = false;
197200
v6only = options.v6only;
198201
nodelay = true;
199-
})
200-
if s == nil then
201-
return nil, err, errno
202+
}
203+
204+
local lasterr, lasterrno = "The name does not resolve for the supplied parameters"
205+
for _, rec in ipairs(records) do
206+
connect_params.family = rec.family;
207+
connect_params.host = rec.host;
208+
connect_params.path = rec.path;
209+
local s
210+
s, lasterr, lasterrno = ca.fileresult(cs.connect(connect_params))
211+
if s then
212+
local c
213+
c, lasterr, lasterrno = negotiate(s, options, timeout)
214+
if c then
215+
-- Force TCP connect to occur
216+
local ok
217+
ok, lasterr, lasterrno = c:connect(deadline and deadline-monotime())
218+
if ok then
219+
return c
220+
end
221+
c:close()
222+
else
223+
s:close()
224+
end
225+
timeout = deadline and deadline-monotime()
226+
end
202227
end
203-
return negotiate(s, options, timeout)
228+
return nil, lasterr, lasterrno
204229
end
205230

206231
return {

0 commit comments

Comments
 (0)