[[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. ** Tools ** [dns_auditer]: Maps names to IP addresses. [Scotty]: Knows DNS. [Tcl DNS server]: [TclDNS]: DNS client. ** Description ** 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 [http://www.faqs.org/rfcs/rfc1034.html] and the DNS protocol by RFC 1035 [http://www.faqs.org/rfcs/rfc1035.html] 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. * (and I wish I'd known about Jochen's one earlier). Anyway - I've submitted mine to [tcllib] and it can be examined at http://sourceforge.net/tracker/?func=detail&aid=520279&group_id=12883&atid=312883 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 "mdsn" } { set state(-nameserver) 224.0.0.251 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]] break } } 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 [http://twapi.sf.net/network.html#get_network_info]. ---- 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: [http://www.isi.edu/~johnh/SOFTWARE/DNS/index.html] [http://www.isi.edu/~johnh/SOFTWARE/DNS/browse.png] <> Glossary | Internet | Package | Protocol