\chapter{DNS Client Library}\label{cha:dns}

The \ex{dns} structure contains a library for querying DNS servers.

Features:
\begin{itemize}
\item Parsing of \texttt{resolv.conf}, including \texttt{search}
  entries. This enables looking up the FQDN of a host.
\end{itemize}

\section{Conditions}

The library defines a set of conditions raised by the procedures of
the library. The supertype of these conditions is \exi{dns-error}.
\defun{dns-error?}{thing}{\boolean}
\begin{desc}
  The predicate for \ex{dns-error} conditions.
\end{desc}
\defun{dns-error->string} {dns-error-condition} {\str}
\begin{desc}
  Returns a string with the description of the condition.
\end{desc}


\defvarx {dns-format-error} {condition}
\defvarx {dns-server-failure} {condition}
\defvarx {dns-name-error} {condition}
\defvarx {dns-not-implemented} {condition}
\defvarx {dns-refused} {condition}

These conditons correspond to errors returned by the DNS server. They
are all subtypes of the \exi{dns-server-error} condition which in
turn is a subtype of \ex{dns-error}.
\defun{dns-server-error?}{thing}{\boolean}
\begin{desc}
  The predicate for \ex{dns-server-error} conditions.
\end{desc}

\defun  {dns-format-error?} {thing} {\boolean}
\defunx {dns-server-failure?} {thing} {\boolean}
\defunx {dns-name-error?} {thing} {\boolean}
\defunx {dns-not-implemented?} {thing} {\boolean}
\defunx {dns-refused?} {thing} {\boolean}
\begin{desc}
  The type predicates for the conditions above.
\end{desc}

\section{High-level Interface}
\def\ipaddr{\textnormal{IP-address\xspace}}
\def\fqdn{\textnormal{FQDN\xspace}}

\defun{dns-lookup-ip}{\fqdn [nameserver list]}{\fqdn}
\begin{desc}
  Given the FQDN of a host, \ex{dns-lookup-ip} returns the IP address.
  The optional argument specifes the nameservers to query, it defaults
  to the ones found in \texttt{/etc/resolv.conf}. \textbf{always uses
    the cache}
\end{desc}

\defun{dns-lookup-ip}{\ipaddr [nameserver list]}{\fqdn}
\begin{desc}
  Looks up the FQDN for the given IP address. The optional argument
  specifes the nameservers to query, it defaults to the ones found in
  \texttt{/etc/resolv.conf}. \textbf{always uses the cache}
\end{desc}

\defun{dns-lookup-nameserver}{name/\ipaddr [nameserver list]}{\ipaddr list}
\begin{desc}
  Looks up an authoritative nameserver for a hostname, returns a list
  of nameservers. The optional argument specifes the nameservers to
  query, it defaults to the ones found in
  \texttt{/etc/resolv.conf}\textbf{Why a list if there is only one and
    why is there only one for wsi hosts?}\textbf{always uses the cache}
\end{desc}

\defun{dns-lookup-mail-exchanger}{name/\ipaddr [nameserver list]}{\fqdn list}
\begin{desc}
  Looks up mail-exchangers for a hostname und returns them in a list
  sorted by preference. \textbf{Always uses the cache}\textbf{why is
    there only one MX for wsi?}
\end{desc}
\defun{socket-address->fqdn}{socket-address cache?}{\fqdn}
\begin{desc}
  Returns the FQDN for of the address bound to argument. The argument
  \var{cache?}  indicates whether the internal cache may be queried to
  obtain the information.
\end{desc}

\defun{maybe-dns-lookup-name}{name}{\ipaddr or \sharpf}
\defunx{maybe-dns-lookup-ip}{\ipaddr}{\fqdn{} or \sharpf}
\begin{desc}
  These procedures provide the same functionality as
  \ex{dns-lookup-name} and \ex{dns-lookup-ip} but return \sharpf{} in
  case of an \ex{dns-error}.
\end{desc}

\defun{host-fqdn} {name/socket-address}{\fqdn}
\defunx{system-fqdn}{}{\fqdn}
\begin{desc}
  \ex{host-fqdn} returns the fully qualified domain name (FQDN) for its
    argument which can be either a unqualified host name or a socket
    address.  The procedure \ex{system-fqdn} returns the FQDN of the
    current host.
\end{desc}

\section{Low-level Interface}

\defun{dns-lookup}{\fqdn/\ipaddr type [nameserver list]}{dns-message}
\begin{desc}
  This is the most general way to submit a DNS query. The return value
  is a DNS message.\textbf{need to explain dns-message}
\end{desc}

\defun{show-dns-message}{dns-message}{\undefined}
\begin{desc}
  Pretty prints a DNS message to standard output.
  \textbf{Better return a string}
\end{desc}

\defun{domains-for-search}{}{\str list}
\begin{desc}
  Parses \texttt{/etc/resolv.conf} and extracts the domains specified
  by the \texttt{search} keyword.
\end{desc}

\section{Host Names}
\defun{is-fqdn?}{\str}{\boolean}
\begin{desc}
  Indicates whether the argument matches the grammar for a fully
  qualified domain name.
  \oops{The current implementation simply searches for a dot in the name}
\end{desc}

\defun{unqualified-hostname}{\str}{\boolean}
\begin{desc}
  Returns true if the argument matches the grammar for a unqualified
  host name
  \oops{This procedure isn't implemented yet}
\end{desc}

\section{Parsing \texttt{/etc/resolv.conf}}
\defun{resolv.conf}{}{symbol$\rightarrow$string alist}
\begin{desc}
  Returns the contents of \texttt{/etc/resolv.conv} as an alist with
  the possible keys \texttt{nameserver}, \texttt{domain},
  \texttt{search}, \texttt{sortlist}, \texttt{options}.
  
  Note that the library caches the contents of
  \texttt{/etc/resolv.conv} and \ex{resolv.conf} only really opens the
  file if its modification time is more recent than the creation time
  of the cache.
\end{desc}
\defun{parse-resolv.conf!}{}{\undefined}
\begin{desc}
  Parses the contents of \texttt{/etc/resolv.conv} and updates the
  internal cache of the library.
\end{desc}
\defun{dns-find-nameserver-list}{}{\fqdn list}
\begin{desc}
  Returns a list of nameservers from \texttt{/etc/resolv.conf}
\end{desc}
\defun{dns-find-nameserver}{}{\fqdn}
\begin{desc}
  Returns the first nameservers found in \texttt{/etc/resolv.conf}.
  \ex{dns-find-nameserver} raises \ex{no-nameservers} if
  \texttt{/etc/resolv.conf} does not contain a \texttt{nameserver}
  entry.
\end{desc}


%%% Local Variables: 
%%% mode: latex
%%% TeX-master: "man"
%%% End: 
