Reputation: 8950
I often find myself in need to test if an internet connection is online or not. In particular, sometimes it happens (on very, very peculiar connections) that UDP is disabled. Now, I figured that one of the most simple ways to test if UDP is available to my connection is through a DNS query.
Now, using some function like getaddrinfo
abstracts away UDP from the query, so that (as far as my understanding goes) if UDP is not available, TCP will be used instead. Now, since I need to test for UDP connections, I will need to forge the UDP packet with the query myself. Moreover, I would like to make the query to a public DNS server (like 8.8.8.8), so that I am certain that the UDP connection is available to talk to external hosts.
So I am wondering: what is the most simple DNS query that I can send via an UDP packet? Could you show me an example that just asks for the ip, say, of google.com to a DNS server?
Upvotes: 2
Views: 1458
Reputation: 25129
I'm not sure I understand your question fully, but the simplest query would be something like SOA
for .
(i.e. the start of authority for the root zone), like this:
$ dig SOA . @8.8.8.8
; <<>> DiG 9.8.3-P1 <<>> SOA . @8.8.8.8
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 46366
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;. IN SOA
;; ANSWER SECTION:
. 4350 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2015102500 1800 900 604800 86400
;; Query time: 36 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Sun Oct 25 21:07:19 2015
;; MSG SIZE rcvd: 92
If you are asking what that looks like as a UDP packet, simply capture it with tcpdump. However, such trivial DNS packets are relatively easy to construct in C - see RFC1035. You may want to use a pre-existing library like c-ares or adns.
Note that as far as I remember, whether your resolver library falls back to TCP is implementation dependent. IIRC glibc on linux does not fall back to TCP, and libresolv on OpenBSD only does if /etc/resolv.conf
contains options tcp
. When using libresolv
programatically you merely need to ensure RES_USEVC
is clear.
If you are looking for example code, 'Stevens' TCP/IP illustrated' is the canonical answer.
Upvotes: 3