utdnsd
, a DNS forwarder serving requests from UDP clients by delegating them to upstream DNS servers with TCP. The idea is from ttdnsd
of Tor Project.
OpenWrt package definition files can be found at waller repository; detailed instructions of how to import them should be included there.
libubox
from OpenWrt project is required. On Mac OS X with MacPorts installed, you can get libubox
installed by using portfiles from macports-openwrt repository.
To build it locally (of course, CMake is required here).
cmake . && make
To configure the build (mainly the DEBUG
option).
ccmake .
Or you can use build-scripts
When run without arguments, help text will be printed to stderr.
Usage: utdnsd [ -qrh ] -l <host[:port]> [ -s <host[:port]> ... ] [ -t <seconds> ]
-l <host[:port]> Address and port to listen to.
-s <host[:port]> Upstream DNS server we ask for service through TCP transport.
-t <seconds> Maximum delay for reconnect attempts (defaults to 5s).
-T <seconds> Maximum delay before the link was considered shoddy (defaults to 5s).
-r Reconnect on tcp connection hup.
-q Be quiet.
-h This output.
Currently, at most 8 -s <host:[port]>
can be specified on the command line. Same upstream server can be specified multiple times with the -s
option.
Example run.
yousong@yousongs-MacBook-Air:~/dev/utdnsd(master)$ ./utdnsd -l 127.0.0.1:8053 -s 202.130.97.66 -s 202.180.160.1 -s 203.91.143.19 -s 202.130.97.65 -s 202.174.131.19 -s 202.181.224.2 -s 202.45.84.58 -s 202.84.255.1
info: connect to 202.130.97.66:53 succeeded.
info: connect to 202.180.160.1:53 succeeded.
info: connect to 203.91.143.19:53 succeeded.
info: connect to 202.130.97.65:53 succeeded.
info: connect to 202.174.131.19:53 succeeded.
info: connect to 202.181.224.2:53 succeeded.
info: connect to 202.45.84.58:53 succeeded.
info: connect to 202.84.255.1:53 succeeded.
info: start serving!
== SIGUSR1 received, statistics follows
> 202.130.97.66:53 state:1 reconn:0 served:42 staging:0 estimate:0 wbuf:0 rbuf:0 sent:1470 recv:13356
> 202.180.160.1:53 state:1 reconn:0 served:9 staging:0 estimate:0 wbuf:0 rbuf:0 sent:315 recv:2367
> 203.91.143.19:53 state:1 reconn:0 served:9 staging:0 estimate:0 wbuf:0 rbuf:0 sent:315 recv:2367
> 202.130.97.65:53 state:1 reconn:0 served:42 staging:0 estimate:0 wbuf:0 rbuf:0 sent:1470 recv:11046
> 202.174.131.19:53 state:1 reconn:0 served:11 staging:0 estimate:0 wbuf:0 rbuf:0 sent:385 recv:3018
> 202.181.224.2:53 state:1 reconn:0 served:35 staging:0 estimate:0 wbuf:0 rbuf:0 sent:1225 recv:9205
> 202.45.84.58:53 state:1 reconn:0 served:28 staging:0 estimate:0 wbuf:0 rbuf:0 sent:980 recv:7364
> 202.84.255.1:53 state:1 reconn:0 served:19 staging:0 estimate:0 wbuf:0 rbuf:0 sent:665 recv:6061
=================== statistics ends
As you can see from the above output, sending SIGUSR1
to utdnsd
will cause it to print some statistics.
Below are some different strategies or situations I came across while doing testing against a varieties of public DNS servers.
-
Only 1 query per TCP connection. Disconnect at the end of that transaction.
114.114.114.114
-
Only 1 connection per IP (this is a guess), other connections may hang or delay with
ACK
,ACK
, ...
If you have got a long list of usable DNS servers and in a decidophobia as to which ones to use. Then some randomness can help.
server_list='hk.txt.1'
total="$(wc -l "$server_list" | awk '{ print $1; }')"
[ "$total" -gt "8" ] && {
total="$(( $total - 8 ))"
pos="$(( $RANDOM % $total ))"
servers="$(sed -n "$pos,$(($pos+7))p" "$server_list")"
} || {
servers="$(cat "$server_list")"
}
sopts=""
for s in $servers; do
sopts="$sopts -s $s"
done
./utdnsd -l 127.0.0.1:8053 $sopts
Test it with dig
, nslookup
.
# use +short for returning only IP adresses.
dig +noshort -p 8053 @127.0.0.1 www.openvpn.net
nslookup www.openvpn.net 127.0.0.1 -port=8053
nslookup www.openvpn.net 127.0.0.1:8053
- A list of domain names from browser history for testing purposes.
-
adns, mainly as a resolver library, http://www.chiark.greenend.org.uk/~ian/adns/
-
ttdnsd from Tor project, https://gitweb.torproject.org/ioerror/ttdnsd.git
-
DNS benchmark using web browser history, tcpdump output, etc.. https://code.google.com/p/namebench/
- Cannot specify port number.
- Looks nice but got loads of complaints.
-
DNS benchmark tool for Windows, https://www.grc.com/dns/benchmark.htm
-
Public DNS services
- Google DNS
- OpenDNS
- V2EX DNS, https://v2ex.com/go/dns