+\subsection{Le funzioni di interrogazione del \textit{resolver}}
+\label{sec:sock_resolver_functions}
+
+Prima di trattare le funzioni usate normalmente nella risoluzione dei nomi a
+dominio conviene trattare in maniera più dettagliata il meccanismo principale
+da esse utilizzato e cioè quello del servizio DNS. Come accennato questo,
+benché in teoria sia solo uno dei possibili supporti su cui mantenere le
+informazioni, in pratica costituisce il meccanismo principale con cui vengono
+risolti i nomi a dominio. Per questo motivo esistono una serie di funzioni di
+libreria che servono specificamente ad esseguire delle interrogazioni verso un
+server DNS, funzioni che poi vengono utilizzate per realizzare le funzioni
+generiche di libreria usate anche dal sistema del \textit{resolver}.
+
+Il sistema del DNS è in sostanza di un database distribuito organizzato in
+maniera gerarchica, i dati vengono mantenuti in tanti server distinti ciascuno
+dei quali si occupa della risoluzione del proprio \textsl{dominio}; i nomi a
+dominio sono organizzati in una struttura ad albero analoga a quella
+dell'albero dei file, con domini di primo livello (come i \texttt{.org}),
+secondo livello (come \texttt{.truelite.it}), ecc. In questo caso le
+separazioni sono fra i vari livelli sono definite dal carattere ``\texttt{.}''
+ed i nomi devono essere risolti da destra verso sinistra.\footnote{per chi si
+ stia chiedendo quale sia la radice di questo albero, cioè l'equivalente di
+ ``\texttt{/}'', la risposta è il dominio speciale ``\texttt{.}'', che in
+ genere non viene mai scritto esplicitamente, ma che, come chiunque abbia
+ configurato un server DNS sa bene, esiste ed è gestito dai cosiddetti
+ \textit{root DNS} che risolvono i domini di primo livello.} Il meccanismo
+funziona con il criterio della \textsl{delegazione}, un server responsabile
+per un dominio di primo livello può delegare la risoluzione degli indirizzi
+per un suo dominio di secondo livello ad un altro server, il quale a sua volta
+potrà delegare la risoluzione di un eventuale sottodominio di terzo livello ad
+un altro server ancora.
+
+In realtà un server DNS è in grado di fare altro rispetto alla risoluzione di
+un nome a dominio in un indirizzo IP; ciascuna voce nel database viene
+chiamata \textit{resource record}, e può contenere diverse informazioni. In
+genere i \textit{resource record} vengono classificati per la \textsl{classe
+ di indirizzi} cui i dati contenuti fanno riferimento, e per il \textsl{tipo}
+di questi ultimi.\footnote{ritroveremo classi di indirizzi e tipi di record
+ più avanti in tab.~\ref{tab:DNS_address_class} e
+ tab.~\ref{tab:DNS_record_type}.} Oggigiorno i dati mantenuti nei server DNS
+sono quasi esclusivamente relativi ad indirizzi internet, per cui in pratica
+viene utilizzata soltanto una classe di indirizzi; invece le corrispondenze
+fra un nome a dominio ed un indirizzo IP sono solo uno fra i vari tipi di
+informazione che un server DNS fornisce normalmente.
+
+L'esistenza di vari tipi di informazioni è un'altro dei motivi per cui il
+\textit{resolver} prevede, rispetto a quelle relative alla semplice
+risoluzione dei nomi, un insieme di funzioni specifiche dedicate
+all'interrogazione di un server DNS; la prima di queste funzioni è
+\funcd{res\_init}, il cui prototipo è:
+\begin{functions}
+ \headdecl{netinet/in.h} \headdecl{arpa/nameser.h} \headdecl{resolv.h}
+ \funcdecl{int res\_init(void)}
+
+Inizializza il sistema del \textit{resolver}.
+
+\bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
+ errore.}
+\end{functions}
+
+La funzione legge il contenuto dei file di configurazione (i già citati
+\file{resolv.conf} e \file{host.conf}) per impostare il dominio di default,
+gli indirizzi dei server DNS da contattare e l'ordine delle ricerche; se non
+sono specificati server verrà utilizzato l'indirizzo locale, e se non è
+definito un dominio di default sarà usato quello associato con l'indirizzo
+locale (ma questo può essere sovrascritto con l'uso della variabile di
+ambiente \texttt{LOCALDOMAIN}). In genere non è necessario eseguire questa
+funzione direttamente in quanto viene automaticamente chiamata la prima volta
+che si esegue una delle altre.
+
+Le impostazioni e lo stato del \textit{resolver} vengono mantenuti in una
+serie di variabili raggruppate nei campi di una apposita struttura \var{\_res}
+usata da tutte queste funzioni. Essa viene definita in \file{resolv.h} ed è
+utilizzata internamente alle funzioni essendo definita come variabile globale;
+questo consente anche di accedervi direttamente all'interno di un qualunque
+programma, una volta che la sia opportunamente dichiarata come:
+\includecodesnip{listati/resolv_option.c}
+
+Tutti i campi della struttura sono ad uso interno, e vengono usualmente
+inizializzati da \func{res\_init} in base al contenuto dei file di
+configurazione e ad una serie di valori di default. L'unico campo che può
+essere utile modificare è \var{\_res.options}, una maschera binaria che
+contiene una serie di bit di opzione che permettono di controllare il
+comportamento del \textit{resolver}.
+
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|p{8cm}|}
+ \hline
+ \textbf{Costante} & \textbf{Significato} \\
+ \hline
+ \hline
+ \const{RES\_INIT} & viene attivato se è stata chiamata
+ \func{res\_init}. \\
+ \const{RES\_DEBUG} & stampa dei messaggi di debug.\\
+ \const{RES\_AAONLY} & accetta solo risposte autoritative.\\
+ \const{RES\_USEVC} & usa connessioni TCP per contattare i server
+ invece che l'usuale UDP.\\
+ \const{RES\_PRIMARY} & interroga soltanto server DNS primari.
+ \\
+ \const{RES\_IGNTC} & ignora gli errori di troncamento, non ritenta la
+ richiesta con una connessione TCP.\\
+ \const{RES\_RECURSE} & imposta il bit che indica che si desidera
+ eseguire una interrogazione ricorsiva.\\
+ \const{RES\_DEFNAMES} & se attivo \func{res\_search} aggiunge il nome
+ del dominio di default ai nomi singoli (che non
+ contengono cioè un ``\texttt{.}'').\\
+ \const{RES\_STAYOPEN} & usato con \const{RES\_USEVC} per mantenere
+ aperte le connesioni TCP fra interrogazioni
+ diverse. \\
+ \const{RES\_DNSRCH} & se attivo \func{res\_search} esegue le ricerche
+ di nomi di macchine nel dominio corrente o nei
+ domini ad esso sovrastanti.\\
+ \const{RES\_INSECURE1} & blocca i controlli di sicurezza di tipo 1.\\
+ \const{RES\_INSECURE2} & blocca i controlli di sicurezza di tipo 2.\\
+ \const{RES\_NOALIASES} & blocca l'uso della variabile di ambiente
+ \texttt{HOSTALIASES}.\\
+ \const{RES\_USE\_INET6} & restituisce indirizzi IPv6 con
+ \func{gethostbyname}. \\
+ \const{RES\_ROTATE} & ruota la lista dei server DNS dopo ogni
+ interrogazione.\\
+ \const{RES\_NOCHECKNAME}& non controlla i nomi per verificarne la
+ correttezza sintattica. \\
+ \const{RES\_KEEPTSIG} & non elimina i record di tipo \texttt{TSIG}.\\
+ \const{RES\_BLAST} & \\
+ \const{RES\_DEFAULT} & è l'insieme di \const{RES\_RECURSE},
+ \const{RES\_DEFNAMES} e \const{RES\_DNSRCH}.\\
+ \hline
+ \end{tabular}
+ \caption{Costanti utilizzabili come valori per \var{\_res.options}.}
+ \label{tab:resolver_option}
+\end{table}
+
+Per utilizzare questa funzionalità per modificare le impostazioni direttamente
+da programma occorrerà impostare un opportuno valore per questo campo ed
+invocare esplicitamente \func{res\_init}, dopo di che le altre funzioni
+prenderanno le nuove impostazioni. Le costanti che definiscono i vari bit di
+questo campo, ed il relativo significato sono illustrate in
+tab.~\ref{tab:resolver_option}; trattandosi di una maschera binaria un valore
+deve essere espresso con un opportuno OR aritmetico di dette costanti; ad
+esempio il valore di default delle opzioni, epsresso dalla costante
+\const{RES\_DEFAULT}, è definito come:
+\includecodesnip{listati/resolv_option_def.c}
+
+Non tratteremo il significato degli altri campi non essendovi necessità di
+modificarli direttamente; gran parte di essi sono infatti impostati dal
+contenuto dei file di configurazione, mentre le funzionalità controllate da
+alcuni di esse possono essere modificate con l'uso delle opportune variabili
+di ambiente come abbiamo visto per \texttt{LOCALDOMAIN}. In particolare con
+\texttt{RES\_RETRY} si soprassiede il valore del campo \var{retry} che
+controlla quante volte viene ripetuto il tentativo di connettersi ad un server
+DNS prima di dichiarare fallimento; il valore di default è 4, un valore nullo
+significa bloccare l'uso del DNS. Infine con \texttt{RES\_TIMEOUT} si
+soprassiede il valore del campo \var{retrans},\footnote{preimpostato al valore
+ della omonima costante \const{RES\_TIMEOUT} di \file{resolv.h}.} che è il
+valore preso come base (in numero di secondi) per definire la scadenza di una
+richiesta, ciascun tentativo di richiesta fallito viene ripetuto raddoppianto
+il tempo di scadenza per il numero massimo di volte stabilito da
+\texttt{RES\_RETRY}.
+
+La funzione di interrogazione principale è \funcd{res\_query}, che serve ad
+eseguire una richiesta ad un server DNS per un nome a dominio
+\textsl{completamente specificato} (quello che si chiama FQDN, \textit{Fully
+ Qualified Domain Name}); il suo prototipo è:
+
+\begin{functions}
+\headdecl{netinet/in.h}
+\headdecl{arpa/nameser.h}
+\headdecl{resolv.h}
+\funcdecl{int res\_query(const char *dname, int class, int type,
+ unsigned char *answer, int anslen)}
+
+ Esegue una interrogazione al DNS.
+
+\bodydesc{La funzione restituisce un valore positivo pari alla lunghezza dei
+ dati scritti nel buffer \param{answer} in caso di successo e -1 in caso di
+ errore.}
+\end{functions}
+
+La funzione esegue una interrogazione ad un server DNS relativa al nome da
+risolvere passato nella stringa indirizzata da \param{dname}, inoltre deve
+essere specificata la classe di indirizzi in cui eseguire la ricerca con
+\param{class}, ed il tipo di \textit{resource record} che si vuole ottenere
+con \param{type}. Il risultato della ricerca verrà scritto nel buffer di
+lunghezza \param{anslen} puntato da \param{answer} che si sarà opportunamente
+allocato in precedenza.
+
+
+Una seconda funzione di ricerca, analoga a \func{res\_query}, che prende gli
+stessi argomenti, ma che esegue l'interrogazione con le funzionalità
+addizionali previste dalle due opzioni \const{RES\_DEFNAMES} e
+\const{RES\_DNSRCH}, è \funcd{res\_search}, il cui prototipo è:
+\begin{functions}
+\headdecl{netinet/in.h}
+\headdecl{arpa/nameser.h}
+\headdecl{resolv.h}
+\funcdecl{int res\_search(const char *dname, int class, int type,
+ unsigned char *answer, int anslen)}
+
+ Esegue una interrogazione al DNS.
+
+ \bodydesc{La funzione restituisce un valore positivo pari alla lunghezza dei
+ dati scritti nel buffer \param{answer} in caso di successo e -1 in caso di
+ errore.}
+\end{functions}
+
+In sostanza la funzione ripete una serie di chiamate a \func{res\_query}
+aggiungendo al nome contenuto nella stringa \param{dname} il dominio di
+default da cercare, fermandosi non appena trova un risultato. Il risultato di
+entrambe le funzioni viene scritto nel formato opportuno (che sarà diverso a
+seconda del tipo di record richiesto) nel buffer di ritorno; sarà compito del
+programma (o di altre funzioni) estrarre i relativi dati, esistono una serie
+di funzioni interne usate per la scansione di questi dati, per chi fosse
+interessato una trattazione dettagliata è riportata nel quattordicesimo
+capitolo di \cite{DNSbind}.
+
+Le classi di indirizzi supportate da un server DNS sono tre, ma di queste in
+pratica oggi viene utilizzata soltanto quella degli indirizzi internet; le
+costanti che identificano dette classi, da usare come valore per l'argomento
+\param{class} delle precedenti funzioni, sono riportate in
+tab.~\ref{tab:DNS_address_class}.\footnote{esisteva in realtà anche una classe
+ \const{C\_CSNET} per la omonima rete, ma è stata dichiarata obsoleta.}
+
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|p{8cm}|}
+ \hline
+ \textbf{Costante} & \textbf{Significato} \\
+ \hline
+ \hline
+ \const{C\_IN} & indirizzi internet, in pratica i soli utilizzati oggi.\\
+ \const{C\_HS} & indirizzi \textit{Hesiod}, utilizzati solo al MIT, oggi
+ completamente estinti. \\
+ \const{C\_CHAOS}& indizzi per la rete \textit{Chaosnet}, un'altra rete
+ sperimentale nata al MIT. \\
+ \const{C\_ANY} & indica un indirizzo di classe qualunque.\\
+ \hline
+ \end{tabular}
+ \caption{Costanti identificative delle classi di indirizzi per l'argomento
+ \param{class} di \func{res\_query}.}
+ \label{tab:DNS_address_class}
+\end{table}
+
+Come accennato le tipologie di dati che sono mantenibili su un server DNS sono
+diverse, ed a ciascuna di essa corriponde un diverso tipo di \textit{resource
+ record}. L'elenco delle costanti\footnote{ripreso dai file di dichiarazione
+ \file{arpa/nameser.h} e \file{arpa/nameser\_compat.h}.} che definiscono i
+valori che si possono usare per l'argomento \param{type} per specificare il
+tipo di \textit{resource record} da richiedere è riportato in
+tab.~\ref{tab:DNS_record_type}; le costanti (tolto il \texttt{T\_} iniziale)
+hanno gli stessi nomi usati per identificare i record nei file di zona di
+BIND,\footnote{BIND, acronimo di \textit{Berkley Internet Name Domain}, è una
+ implementazione di un server DNS, ed, essendo utilizzata nella stragrande
+ maggioranza dei casi, fa da rifererimento; i dati relativi ad un certo
+ dominio (cioè i suoi \textit{resource record} vengono mantenuti in quelli
+ che sono usualmente chiamati \textsl{file di zona}, e in essi ciascun tipo
+ di dominio è identificato da un nome che è appunto identico a quello delle
+ costanti di tab.~\ref{tab:DNS_record_type} senza il \texttt{T\_} iniziale.}
+e che normalmente sono anche usati come nomi per indicare i record.
+
+\begin{table}[!htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|l|}
+ \hline
+ \textbf{Costante} & \textbf{Significato} \\
+ \hline
+ \hline
+ \const{T\_A} & indirizzo di una stazione.\\
+ \const{T\_NS} & server DNS autoritativo per il dominio richiesto.\\
+ \const{T\_MD} & destinazione per la posta elettronica.\\
+ \const{T\_MF} & redistributore per la posta elettronica.\\
+ \const{T\_CNAME} & nome canonico.\\
+ \const{T\_SOA} & inzio di una zona di autorità.\\
+ \const{T\_MB} & nome a dominio di una casella di posta.\\
+ \const{T\_MG} & nome di un membro di un gruppo di posta.\\
+ \const{T\_MR} & nome di un cambiamento di nome per la posta.\\
+ \const{T\_NULL} & record nullo.\\
+ \const{T\_WKS} & servizio noto.\\
+ \const{T\_PTR} & risoluzione inversa di un indirizzo numerico.\\
+ \const{T\_HINFO} & informazione sulla stazione.\\
+ \const{T\_MINFO} & informazione sulla casella di posta.\\
+ \const{T\_MX} & server cui instradare la posta per il dominio.\\
+ \const{T\_TXT} & stringhe di testo (libere).\\
+ \const{T\_RP} & nome di un responsabile (\textit{responsible person}).\\
+ \const{T\_AFSDB} & database per una cella AFS.\\
+ \const{T\_X25} & indirizzo di chiamata per X.25.\\
+ \const{T\_ISDN} & indirizzo di chiamata per ISDN.\\
+ \const{T\_RT} & router.\\
+ \const{T\_NSAP} & indirizzo NSAP.\\
+ \const{T\_NSAP\_PTR}& risoluzione inversa per NSAP (deprecato).\\
+ \const{T\_SIG} & firma digitale di sicurezza.\\
+ \const{T\_KEY} & chiave per firma.\\
+ \const{T\_PX} & corrispondenza per la posta X.400.\\
+ \const{T\_GPOS} & posizione grografica.\\
+ \const{T\_AAAA} & indirizzo IPv6.\\
+ \const{T\_LOC} & informazione di collocazione.\\
+ \const{T\_NXT} & dominio successivo.\\
+ \const{T\_EID} & identificatore di punto conclusivo.\\
+ \const{T\_NIMLOC}& posizionatore \textit{nimrod}.\\
+ \const{T\_SRV} & servizio.\\
+ \const{T\_ATMA} & indirizzo ATM.\\
+ \const{T\_NAPTR} & puntatore ad una \textit{naming authority} .\\
+ \const{T\_TSIG} & firma di transazione.\\
+ \const{T\_IXFR} & trasferimento di zona incrementale.\\
+ \const{T\_AXFR} & trasferimento di zona di autorità.\\
+ \const{T\_MAILB} & trasferimento di record di caselle di posta.\\
+ \const{T\_MAILA} & trasferimento di record di server di posta.\\
+ \const{T\_ANY} & valore generico.\\
+ \hline
+ \end{tabular}
+ \caption{Costanti identificative del tipo di record per l'argomento
+ \param{type} di \func{res\_query}.}
+ \label{tab:DNS_record_type}
+\end{table}
+
+
+L'elenco di tab.~\ref{tab:DNS_record_type} è quello di \textsl{tutti} i
+\textit{resource record} definiti, con una breve descrizione del relativo
+significato. Di tutti questi però viene impiegato correntemente solo un
+piccolo sottoinsieme, alcuni sono obsoleti ed altri fanno riferimento a dati
+applicativi che non ci interessano non avendo nulla a che fare con la
+risoluzione degli indirizzi IP, pertanto non entreremo nei dettagli del
+significato di tutti i \textit{resource record}, ma solo di quelli usati dalle
+funzioni del \textit{resolver}. Questi sono sostanzialmente i seguenti (per
+indicarli si è usata la notazione dei file di zona di BIND):
+\begin{basedescript}{\desclabelwidth{1.2cm}\desclabelstyle{\nextlinelabel}}
+\item[\texttt{A}] viene usato per indicare la corripondenza fra un nome a
+ dominio ed un indirizzo IPv4; ad esempio la corrispondenza fra
+ \texttt{dodds.truelite.it} e l'indirizzo IP \texttt{62.48.34.25}.
+\item[\texttt{AAAA}] viene usato per indicare la corrispondenza fra un nome a
+ dominio ed un indirizzo IPv6; è chiamato in questo modo dato che la
+ dimensione di un indirizzo IPv6 è quattro volte quella di un indirizzo IPv4.
+\item[\texttt{PTR}] per fornire la corripondenza inversa fra un indirizzo IP
+ ed un nome a dominio ad esso associato si utilizza questo tipo di record (il
+ cui nome sta per \textit{pointer}).
+\item[\texttt{CNAME}] qualora si abbiamo più nomi che corrispondono allo
+ stesso indirizzo (come ad esempio \texttt{www.truelite.it}, o
+ \texttt{sources.truelite.it}, che fanno sempre riferimento a
+ \texttt{dodds.truelite.it}) si può usare questo tipo di record per creare
+ degli \textit{alias} in modo da associare un qualunque altro nome al
+ \textsl{nome canonico} della macchina (si chiama così quello associato al
+ record \texttt{A}).
+\end{basedescript}
+
+Come accennato in caso di successo le due funzioni di richiesta restituiscono
+il risultato della interrogazione al server, in caso di insuccesso l'errore
+invece viene segnalato da un valore di ritorno pari a -1, ma in questo caso,
+non può essere utilizzata la variabile \var{errno} per riportare un codice di
+errore, in quanto questo viene impostato per ciascuna delle chiamate al
+sistema utilizzate dalle funzioni del \textit{resolver}, non avrà alcun
+significato nell'indicare quale parte del procedimento di risoluzione è
+fallita.
+
+Per questo motivo è stata definita una variabile di errore separata,
+\var{h\_errno}, che viene utilizzata dalle funzioni del \textit{resolver} per
+indicare quale problema ha causato il fallimento della risoluzione del nome.
+Ad essa si può accedere una volta che la si dichiara con:
+\includecodesnip{listati/herrno.c}
+ed i valori che può assumere, con il relativo significato, sono riportati in
+tab.~\ref{tab:h_errno_values}.
+
+\begin{table}[!htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|p{10cm}|}
+ \hline
+ \textbf{Costante} & \textbf{Significato} \\
+ \hline
+ \hline
+ \const{HOST\_NOT\_FOUND} & l'indirizzo richiesto non è valido e la
+ macchina indicata è sconosciuta. \\
+ \const{NO\_ADDRESS} & il nome a dominio richiesto è valido, ma non ha
+ un indirizzo associato ad esso
+ (alternativamente può essere indicato come
+ \const{NO\_DATA}). \\
+ \const{NO\_RECOVERY} & si è avuto un errore non recuperabile
+ nell'interrogazione di un server DNS. \\
+ \const{TRY\_AGAIN} & si è avuto un errore temporaneo
+ nell'interrogazione di un server DNS, si può
+ ritentare l'interrogazione in un secondo
+ tempo. \\
+ \hline
+ \end{tabular}
+ \caption{Valori possibili della variabile \var{h\_errno}.}
+ \label{tab:h_errno_values}
+\end{table}
+
+Insieme alla nuova variabile vengono definite anche due nuove funzioni per
+stampare l'errore a video, analoghe a quelle di sez.~\ref{sec:sys_strerror}
+per \var{errno}, ma che usano il valore di \var{h\_errno}; la prima è
+\funcd{herror} ed il suo prototipo è:
+\begin{functions}
+\headdecl{netdb.h}
+\funcdecl{void herror(const char *string)}
+
+Stampa un errore di risoluzione.
+\end{functions}
+
+La funzione è l'analoga di \func{perror} e stampa sullo standard error un
+messaggio di errore corrispondente al valore corrente di \var{h\_errno}, a cui
+viene anteposta la stringa \param{string} passata come argomento. La seconda
+funzione è \funcd{hstrerror} ed il suo prototipo è:
+\begin{functions}
+\headdecl{netdb.h}
+\funcdecl{const char *hstrerror(int err)}
+
+Restituisce una stringa corripondente ad un errore di risoluzione.
+\end{functions}
+\noindent che, come l'analoga \func{strerror}, restituise una stringa con un
+messaggio di errore già formattato, corrispondente al codice passato come
+argomento (che si presume sia dato da \var{h\_errno}).
+
+
+