Skip to content

Instantly share code, notes, and snippets.

@ylxdzsw
Created September 19, 2018 04:55
Show Gist options
  • Save ylxdzsw/7abb58bac742276df09b8545cff2bfc6 to your computer and use it in GitHub Desktop.
Save ylxdzsw/7abb58bac742276df09b8545cff2bfc6 to your computer and use it in GitHub Desktop.
see if you got a bad dns server
using Fire
using Dates
using Base64
using Sockets
using OhMyJulia
using Statistics
import Base.adjoint # monky patch
adjoint(x::Unsigned) = ntoh(x)
const list = [
"www.baidu.com",
"www.google.com",
"scholar.google.com.hk",
"stackoverflow.com",
"en.wikipedia.org",
"zh.wikipedia.org",
"www.sharelatex.com"
]
function pack_dns_query(website, id::u16=rand(u16))
buf = IOBuffer()
buf << asbytes(id') << asbytes(0b0_0000_0_0_1_0_000_0000')
buf << asbytes(0x0001') << asbytes(0x0000) << asbytes(0x0000) << asbytes(0x0000)
qname = mapreduce(++, split(website, '.')) do seg
l = length(seg)
(l % u8) ++ Bytes(seg)
end
buf << qname << asbytes(0x00) << asbytes(0x0001') << asbytes(0x0001') >> take!
end
function get_default_dns_linux()
first(cadr(split(line)) for line in eachline("/etc/resolv.conf") if startswith(line, "nameserver"))
end
@main function record_ng(server=get_default_dns_linux())
server = IPv4(server)
prt("time", "website", "status", "elapsed(ms)", "info")
locks = Lock(@fill(UDPSocket(), 4))
while true
waitfor(x->!isempty(x), locks)
socket = pop!(locks[])
@async let socket = socket
sleep(2rand())
website = rand(list)
msg = pack_dns_query(website)
starttime = time()
done = false
task = @async try
send(socket, server, 53, msg)
result = recv(socket)
prt(Dates.format(Dates.now(), "HH:MM:SS"), website, "succeed", floor(Int, 1000(time() - starttime)), base64encode(result))
catch e
print(Dates.format(Dates.now(), "HH:MM:SS\t"), website, "\tfailed\t", floor(Int, 1000(time() - starttime)), '\t')
show(e)
println()
finally
done = true
flush(stdout)
locks[:one] = locks[] ++ socket
end
@async begin # timeout
sleep(5)
if (!done)
close(socket)
socket = UDPSocket()
end
end
fetch(task)
end
end
end
@main function record()
prt("time", "website", "status", "elapsed(ms)", "info")
l = Lock(4)
while true
waitfor(x->x>0, l)
l[] -= 1
@async let
sleep(rand())
starttime = time()
website = rand(list)
try
info = getalladdrinfo(website)
prt(Dates.format(Dates.now(), "HH:MM:SS"), website, "succeed", floor(Int, 1000(time() - starttime)), join(info, ", "))
catch e
print(Dates.format(Dates.now(), "HH:MM:SS\t"), website, "\tfailed\t", floor(Int, 1000(time() - starttime)), '\t')
show(e)
println()
finally
flush(stdout)
l[:one] += 1
end
end
end
end
@main function stat(file)
a = readlines(file)[2:end]
a = map(x->split(x, '\t'), a)
a = groupby(x->x[2], (x, y) -> push!(x, (y[3], parse(Int, y[4]))), ()->[], a)
for (k, v) in a
s = filter(x->car(x) == "succeed", v)
r = floor(100(length(s) / length(v)), digits=2)
println(k, " Success rate: $r%, average time: $(floor(Int, mean(cadr.(s))))ms")
end
end
@main function cdf(file)
a = readlines(file)[2:end]
a = map(x->split(x, '\t'), a)
a = groupby(x->x[2], (x, y) -> push!(x, parse(Int, y[4])), ()->[], a)
str = s"""
\documentclass[tikz]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}
\pgfplotsset{every axis legend/.append style={%
cells={anchor=west}}
}
\begin{document}
\begin{tikzpicture}[]
\begin{axis}[%
grid=both,
grid style={line width=.1pt, draw=gray!20},
ylabel={CDF},
xlabel={Lantency (s)},
width=12cm,
height=9cm,
ymin=0,
ymax=1,
legend style={
at = {(.99,.015)},
anchor = south east,
font = \fontsize{8pt}{8pt}\selectfont,
row sep=-1pt
},
legend image post style={scale=0.8},
]
"""
for (k, v) in a
g = level_to_edge(sort(v))
x = map(cadr, g) ./ 1000
y = ((map(car, g)[2:end] .- 1) ./ length(v)) ++ 1
str *= """
\\addplot+[mark=none] coordinates {
$(join(zip(x, y), '\n'))
};
\\addlegendentry{$k}
"""
end
println(str, s"""
\end{axis}
\end{tikzpicture}
\end{document}
""")
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment