[Domain Name System] DNS, or Domain Name System, is a distributed database that maps domain names to IP addresses so that we don't have to remember lots of numbers to navigate the internet.

See Also

The DNS blocking problem
DNS Library Revisited, by EF
Automatically obtains local DNS settings. Caches DNS lookups.


Maps names to IP addresses.
Knows DNS.
Tcl DNS server
DNS client.


Domain lookups (also termed name resolution) is done using a DNS client library, the resolver, that is normally part of the system C library via the gethostbyname familly of calls. See resolver(5) and gethostbyname(3).

The architecture is described by RFC 1034 [L1 ] and the DNS protocol by RFC 1035 [L2 ]

One of the problems Tcl applications can encounter is that DNS resolution can be slow and processing is usually blocked while waiting for the DNS query to complete. This is because when you attempt to resolve a domain name, your local nameserver may need to ask another, who may need to ask another. DNS typically uses UDP so will retry queries a number of times using increasingly large delays between each retry. The net effect is that it can take up to 2 minutes to fail to resolve a domain name. In the meantime your application may be unresponsive the entire time as the thread of control is locked up in the resolver library and not running Tcl.

To deal with this issue it is possible to perform lookups using Tcl only and deal with the replies using Tcl's fileevent system. This should allow the application to remain responsive.

Jochen Loewer has written a pure-Tcl implementation.

Pat Thoyts has written a pure-Tcl (client TCP and UDP) implementation.

In March 2002 or so, tcllib acquired its own dns package.

Documentation for the Tcllib dns package can be found at http://tcllib.sourceforge.net/doc/dns.html

If you need to discuss the Tcllib dns implementation, a new page might be in order ...

PT 2003-02-25: The Tcllib DNS package can use UDP using a modified version of the TclUDP package (modified to support binary packets). I'll try to sort out releasing the modified code. To setup the DNS package for this:

package require udp 1.0.2
package require dns 1.0.2
dns::configure -protocol udp

jbr 2011-05-27: mDNS for dns : Here is a replacement for part of the [tcllib] dns resolver in dns.tcl.

proc ::dns::UdpTransmit {token} {
    # FRINK: nocheck
    variable $token
    upvar 0 $token state

    # setup the timeout
    if {$state(-timeout) > 0} {
        set state(after) [after $state(-timeout) \
                              [list [namespace origin reset] \
                                   $token timeout\
                                  "operation timed out"]]
    if {[llength [package provide ceptcl]] > 0} {
        # using ceptcl
        set state(sock) [cep -type datagram $state(-nameserver) $state(-port)]
        fconfigure $state(sock) -blocking 0
    } else {
        # using tcludp
        set state(sock) [udp_open]
        if { $state(-protocol) eq "mdns" } {
            set state(-nameserver)
            set state(-port)       5353
            udp_conf $state(sock) $state(-nameserver) $state(-port)
        } else {
            udp_conf $state(sock) $state(-nameserver) $state(-port)
    fconfigure $state(sock) -translation binary -buffering none
    set state(status) connect
    puts -nonewline $state(sock) $state(request)
    fileevent $state(sock) readable [list [namespace current]::UdpEvent $token]
    return $token

Use like this:

::dns::resolve desired-machine.local -protocol mdns

When using the dns package of Tcllib, you have to know which DNS server to use for host name resolutions. Your machine probably already knows that somewhere, it is just a matter of finding this information in a portable way. I have used the following script to perform this operation, it works on Windows and should on a decent UNIX system. For once, both architecture actually support the same binary name for the same service!! Feel free to adapt and use. EF

set res [catch "exec nslookup localhost" lkup]
if { $res == 0 } {
    set l [split $lkup]
    set nl ""
    foreach e $l {
        if { [string length $e] > 0 } {
            lappend nl $e

    set hostname ""
    set len [llength $nl]
    for { set i 0 } { $i < $len } { incr i } {
        set e [lindex $nl $i]
        if { [string match -nocase "*server*" $e] } {
            set hostname [lindex $nl [expr $i + 1]]

    if { $hostname ne "" } {
        puts "Primary DNS server is: $hostname"
    } else {
        puts "Could not find primary DNS server!"
} else {
  puts "Could not execute nslookup!"

KPV : On my windows box, nslookup localhost fails but I can get the DNS Server info by running ipconfig /all.

APN : On Windows NT+, if you have TWAPI, you can use the command

get_network_info -dnsservers

See [L3 ].

dns_tree is a command-line-based front-end to dig. It replaces the several dig invocations necessary to fetch a zone, and it formats the output in a somewhat sensible hierarchical style (a tree).

dns_browse is a GUI front-end to dns_tree. It allows point-and-click DNS browsing and makes it easy to expand/compress hierarchies in one or more DNS zones.

Available at: [L4 ]