dns server auto retire

This commit is contained in:
Cloud Wu
2018-01-25 15:56:47 +08:00
parent cd99557368
commit 084aab4bcd
2 changed files with 53 additions and 11 deletions

View File

@@ -219,7 +219,12 @@ local function unpack_rdata(qtype, chunk)
end
end
local dns_server
local dns_server = {
fd = nil,
address = nil,
port = nil,
retire = nil,
}
local function resolve(content)
if #content < DNS_HEADER_LEN then
@@ -281,6 +286,33 @@ local function resolve(content)
skynet.wakeup(resp.co)
end
local DNS_SERVER_RETIRE = 60 * 100
local function touch_server()
dns_server.retire = skynet.now()
if dns_server.fd then
return
end
dns_server.fd = socket.udp(function(str, from)
resolve(str)
end)
skynet.error(string.format("Udp server open %s:%s (%d)", dns_server.address, dns_server.port, dns_server.fd))
socket.udp_connect(dns_server.fd, dns_server.address, dns_server.port)
local function check_alive()
if skynet.now() > dns_server.retire + DNS_SERVER_RETIRE then
local fd = dns_server.fd
if fd then
dns_server.fd = nil
socket.close(fd)
skynet.error(string.format("Udp server close %s:%s (%d)", dns_server.address, dns_server.port, fd))
end
else
skynet.timeout( 2 * DNS_SERVER_RETIRE, check_alive)
end
end
skynet.timeout( 2 * DNS_SERVER_RETIRE, check_alive)
end
function dns.server(server, port)
if not server then
local f = assert(io.open "/etc/resolv.conf")
@@ -293,11 +325,11 @@ function dns.server(server, port)
f:close()
assert(server, "Can't get nameserver")
end
dns_server = socket.udp(function(str, from)
resolve(str)
end)
socket.udp_connect(dns_server, server, port or 53)
return server
assert(dns_server.fd == nil) -- only set dns.server once
dns_server.address = server
dns_server.port = port or 53
touch_server()
return dns_server.address
end
local function lookup_cache(name, qtype, ignorettl)
@@ -354,8 +386,9 @@ function dns.resolve(name, ipv6)
qdcount = 1,
}
local req = pack_header(question_header) .. pack_question(name, qtype, QCLASS.IN)
assert(dns_server, "Call dns.server first")
socket.write(dns_server, req)
assert(dns_server.address, "Call dns.server first")
touch_server()
socket.write(dns_server.fd, req)
return suspend(question_header.tid, name, qtype)
end

View File

@@ -1,11 +1,20 @@
local skynet = require "skynet"
local dns = require "skynet.dns"
local resolve_list = {
"github.com",
"stackoverflow.com",
"lua.com",
}
skynet.start(function()
print("nameserver:", dns.server()) -- set nameserver
-- you can specify the server like dns.server("8.8.4.4", 53)
local ip, ips = dns.resolve "github.com"
for k,v in ipairs(ips) do
print("github.com",v)
for _ , name in ipairs(resolve_list) do
local ip, ips = dns.resolve(name)
for k,v in ipairs(ips) do
print(name,v)
end
skynet.sleep(500) -- sleep 5 sec
end
end)