Created
August 3, 2022 11:38
-
-
Save wildrun0/f2e11676942b5a3592eee65d735ef2cf to your computer and use it in GitHub Desktop.
DNS LATENCY TEST for Pi-hole (lua)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local cURL = require "cURL" | |
-- caching functions to get faster loop experience | |
local str_gmatch = string.gmatch | |
local str_find = string.find | |
function string:split(sep) | |
local i = 1 | |
local t = {} | |
for token in str_gmatch(self, "[^" .. sep .. "]+") do | |
t[i] = token | |
i = i + 1 | |
end | |
return t | |
end | |
local output_file_name = "dns-bench-output.txt" | |
local file, err = io.open(output_file_name,'a') | |
if not file then | |
print(err) | |
return | |
end | |
local function write_to_file(...) | |
for i = 1, select("#", ...) do | |
local text = select(i, ...) | |
file:write(text, "\n") | |
end | |
end | |
local print = function(...) | |
print(...) | |
write_to_file(...) | |
end | |
print("\nPerfoming a ping test through all Pi-hole upstream dns providers\nDownloading page...") | |
local body_html = "" | |
local function save_page(data) | |
body_html = body_html .. data | |
end | |
local c, err = cURL.easy{ | |
url = "https://docs.pi-hole.net/guides/dns/upstream-dns-providers/", | |
ssl_verifypeer = false, | |
ssl_verifyhost = false, | |
writefunction=save_page | |
}:perform() | |
local status = c:getinfo_response_code() | |
print("curl status: " .. status..string.format(" [%s]", status == 200 and "Done" or "Fail")) | |
if status ~= 200 then return end | |
local function get_tag(body_text, tag, explict_tag) | |
local i = 1 | |
local t = {} | |
local pattern = explict_tag and "<"..tag..".->(.-)</"..tag..">" or "<"..tag..">(.-)</"..tag..">" | |
for v in str_gmatch(body_text, pattern) do | |
t[i] = v | |
i = i + 1 | |
end | |
return t | |
end | |
local dns_names = get_tag(body_html, "h3", true) | |
local uls = get_tag(body_html, "ul", false) | |
table.remove(uls, 3) -- we are not going to use opendns FamilyShield nah fam | |
local os_isWin = os.getenv('OS') and true or false | |
local ipv6_support = true | |
local pings = {} | |
for i = 1, #dns_names do | |
local dns_query = uls[i]:split("\n") | |
local dns_name = dns_names[i]:split("<")[1] | |
if dns_name == "Custom" then break end | |
print("\n"..dns_name) | |
local ping = {} | |
for v = 1, #dns_query do | |
local dns_ip = dns_query[v]:split("<li>")[1] | |
local is_v6 = false | |
if string.match(dns_ip, "(IPv6)") then | |
if not ipv6_support then | |
break | |
end | |
dns_ip = dns_ip:split(" ")[1] | |
is_v6 = true | |
end | |
print(dns_ip) | |
local ping_cmd = os_isWin and "ping "..dns_ip or "ping -c 4 "..dns_ip | |
if is_v6 then | |
ping_cmd = os_isWin and ping_cmd or "ping6 "..dns_ip | |
end | |
local pipe = io.popen(ping_cmd) | |
local output = pipe:read("*all") | |
local output_splitted = os_isWin and output:split("=") or output:split("/") | |
local measured_ping = output_splitted[os_isWin and #output_splitted or #output_splitted-2] | |
if ipv6_support then | |
if not measured_ping or str_find(measured_ping:gsub("%s+", ""), "4%(100%%") then -- 4(100% lost) | |
ipv6_support = false | |
print("IPv6 not supported. Skipping") | |
break | |
end | |
end | |
ping[v] = tonumber(measured_ping:match("%S+")) | |
pipe:close() | |
end | |
pings[dns_name] = ping | |
print("Measured ping: "..table.concat(ping, ", ")) | |
end | |
local function get_lowest(table) | |
local min = math.huge | |
for i = 1, #table do | |
local num = table[i] | |
if min > num then | |
min = num | |
end | |
end | |
return min | |
end | |
print("\nPING DNS SERVICE") | |
local best_dns | |
local min = math.huge | |
for dns, dns_pings in pairs(pings) do | |
local dns_lowest_ping = get_lowest(dns_pings) | |
if min > dns_lowest_ping then | |
min = dns_lowest_ping | |
best_dns = dns | |
end | |
print(string.format("%.1f", dns_lowest_ping) .. "ms" .. " "..dns) | |
end | |
print("\nYour best choice would be: " .. best_dns .. "\nLatency(ms): " .. min) | |
print("\nOutput saved to "..output_file_name) | |
file:close() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
ATTENTION!
Lua-cURL required