File

net/resolvers/basic.lua @ 11539:3413fea9e6db 0.11

util.startup: Set more aggressive defaults for GC Testing has demonstrated that the default GC parameters are not sufficient to prevent runaway memory growth when running under Lua 5.2 and Lua 5.3. Setting the GC speed to 500 was tested on Lua versions 5.1->5.4 and did not display unbounded memory growth.
author Matthew Wild <mwild1@gmail.com>
date Fri, 07 May 2021 16:41:39 +0100
parent 11007:1d8e1f7a587c
child 11008:fd735fe2fc50
line wrap: on
line source

local adns = require "net.adns";
local inet_pton = require "util.net".pton;
local inet_ntop = require "util.net".ntop;
local idna_to_ascii = require "util.encodings".idna.to_ascii;

local methods = {};
local resolver_mt = { __index = methods };

-- Find the next target to connect to, and
-- pass it to cb()
function methods:next(cb)
	if self.targets then
		if #self.targets == 0 then
			cb(nil);
			return;
		end
		local next_target = table.remove(self.targets, 1);
		cb(unpack(next_target, 1, 4));
		return;
	end

	if not self.hostname then
		-- FIXME report IDNA error
		cb(nil);
		return;
	end

	local targets = {};
	local n = 2;
	local function ready()
		n = n - 1;
		if n > 0 then return; end
		self.targets = targets;
		self:next(cb);
	end

	-- Resolve DNS to target list
	local dns_resolver = adns.resolver();
	dns_resolver:lookup(function (answer)
		if answer then
			for _, record in ipairs(answer) do
				table.insert(targets, { self.conn_type.."4", record.a, self.port, self.extra });
			end
		end
		ready();
	end, self.hostname, "A", "IN");

	dns_resolver:lookup(function (answer)
		if answer then
			for _, record in ipairs(answer) do
				table.insert(targets, { self.conn_type.."6", record.aaaa, self.port, self.extra });
			end
		end
		ready();
	end, self.hostname, "AAAA", "IN");
end

local function new(hostname, port, conn_type, extra)
	local ascii_host = idna_to_ascii(hostname);
	local targets = nil;
	conn_type = conn_type or "tcp";

	local is_ip = inet_pton(hostname);
	if not is_ip and hostname:sub(1,1) == '[' then
		is_ip = inet_pton(hostname:sub(2,-2));
	end
	if is_ip then
		hostname = inet_ntop(is_ip);
		if #is_ip == 16 then
			targets = { { conn_type.."6", hostname, port, extra } };
		elseif #is_ip == 4 then
			targets = { { conn_type.."4", hostname, port, extra } };
		end
	end

	return setmetatable({
		hostname = ascii_host;
		port = port;
		conn_type = conn_type;
		extra = extra;
		targets = targets;
	}, resolver_mt);
end

return {
	new = new;
};