More often than not, an application has dependecies to a backend: whether it is a frontend to a relational database system on which the schema might change, or be it a program that retrieves data from an LDAP directory server on which object classes may be modified, it is important to keep the frontend of the “fat client” in sync with the backend. A ubiquitious way of doing that is to compare some sort of version or release number to ensure that the frontend and the backend are compatible.
Several methods can be used to ensure release correlation between the front and
backends; an HTTP GET request to a CGI script might retrieve version
information which is then compared, a
SELECT current_version FROM table can
do similar on a relational database backend, or even a setting in a
configuration store on the client machine, such as the registry on Windows
clients and servers.
A method which is seldom used is DNS. The Domain Name System is a huge distributed database (arguably the World’s largest distributed information database), which is generally used for translating hostnames such as www.example.com to their current TCP/IP address such as 10.254.138.203. The DNS orders the information it holds in so-called resource records (RR) of which there are many types: the A resource record holds an IP address, the MX RR stores a mail-exchanger name with its priority, the NS RR documents which Name Server(s) are authoritative for a domain, etc. One seldom used resource record is the TXT RR, which can hold an arbitrary string of up to 65535 octets.
In standard BIND notation, a DNS file (called a zone) for these four types of records looks like this:
Note how each line is formatted according to the type of information the resource record is allow to contain, and notes once again, that the TXT RR may contain an arbitrary string. To read up on DNS, I reccomend the WikiPedia article and for a good online guide to the working of the BIND (the Berkeley Internet Name Daemon) DNS for Rocket Scientists. One of the best books is Pro DNS and BIND.
The resource record I am interested in is the TXT RR. If I query this resource record with a tool able to retrieve different types of RR (ping is not a suitable utility for doing this) I would get something like this displayed:
How about using such a resource record to distribute the current application version? This technique will work over the Internet accross continents and within organizations that maintain their own Domain Name System servers. A query to the DNS is a very lightweight operation (a single UDP datagram will often suffice in returning the desired data) and it is cached by intermediary name servers (as long as the time to live (TTL) of the resource record hasn’t expired) which reduces the load on the origin DNS server. A TXT RR is a good place to store our information, even though there are valid reasons against doing so.
The DNS administrator of your domain (be it on an internal corporate network or on the Internet) will have to update the record for you, unless she or he allows you to perform dynamic DNS updates.
Choose a hostname for the TXT RR which will uniquely identify your application. Since hostnames can be quite long (254 characters), and since nobody will have to type in this hostname, you can allocate almost anything. There is no danger in having names clash in the future either. By that I mean, suppose you wanted a TXT record called supercool.example.com and later you need a host with the same name, the DNS administrator would later simply add an A RR to supercool.example.com with the address of the host.
To avoid TXT RR other than those that contain our release/version information
from “polluting” us, I have decided to have the resource record contain the
version_ in its value. This will allow constructs such as the
Note how there are three TXT RR for the domain name vers.example.com. Oh,
and do note, that the Domain Name System is designed to return the three
values in arbitrary, usually round-robin type, order to the program that
issues a query for the resource record. For this reason, and to allow entries
that don’t specify a release number for our software, I’ve used the notation
on the last line in the example above; the program will simply remove the
"version_" from the string before interpreting it.
Here is a small C function which has been tested on Windows XP, Windows 2003, as well as several flavors of Linux and Unix of course. Compilation instructions are located at the top of the program for both Linux/Unix and Windows. The latter was compiled with Microsoft Visual C++ 6.0 and the Microsoft Platform SDK.
The Unix/Linux version of the code utilitzes the resolver stubs
resolve.h, which are Copyright (c) 1995, 1996, 1997
Kungliga Tekniska Hvgskolan (Royal Institute of Technology, Stockholm,
What should the program do if the release/version information returned from the DNS doesn’t match what is expected? Well, that very strongly depends on whether the application can continue to work or not. Some programmers might prefer to have the program abort with a diagnostic message and force the user to install a newer version. Others might be able to perform a remote software installation for the new program version. Yet again others, might decide to let the program continue, but instruct the “backend” to use a previous data version. There are innumerable scenarios, and I can only hint at some of the probable ones.
The only package I know of to use a similar technology is the excellent ClamAV scanning toolkit for Linux/Unix; its freshclam tool checks the value of a TXT RR to determine whether new signatures are available. The TXT resource record also contains a timestamp.