\file{/etc/hosts}.
Per questo aspetto il file di configurazione principale del sistema è
-\file{/etc/resolv.conf} che contiene in sostanza l'elenco dei server DNS da
-contattare; a questo si affianca il file \file{/etc/host.conf} il cui scopo
-principale è indicare l'ordine in cui eseguire la risoluzione dei nomi (se
-usare prima i valori di \file{/etc/hosts} o quelli del DNS). Tralasciamo i
-dettagli relativi alle varie direttive che possono essere usate in questi
-file, che si trovano nelle rispettive pagine di manuale.
+\file{/etc/resolv.conf} che contiene in sostanza l'elenco degli indirizzi IP
+dei server DNS da contattare; a questo si affianca il file
+\file{/etc/host.conf} il cui scopo principale è indicare l'ordine in cui
+eseguire la risoluzione dei nomi (se usare prima i valori di \file{/etc/hosts}
+o quelli del DNS). Tralasciamo i dettagli relativi alle varie direttive che
+possono essere usate in questi file, che si trovano nelle rispettive pagine di
+manuale.
Con il tempo però è divenuto possibile fornire diversi sostituti per
l'utilizzo delle associazione statiche in \file{/etc/hosts}, inoltre oltre
di utenti e gruppi e di autenticazione, oggi è sempre più spesso sostituito
da LDAP.} o come quelli dei protocolli e dei servizi che sono mantenuti nei
file statici \file{/etc/protocols} e \file{/etc/services}. Molte di queste
-informazioni non si trovano su un DNS, e poi in un ambiente distribuito può
-essere molto utile centralizzare il mentenimento di alcune di esse su
-opportuni server. Inoltre l'uso di diversi supporti possibili per le stesse
-informazioni (ad esempio il nome delle macchine può essere mantenuto sia
-tramite \file{/etc/hosts}, che con il DNS, che con NIS) comporta il problema
+informazioni non si trovano su un DNS, ma in una rete locale può essere molto
+utile centralizzare il mentenimento di alcune di esse su opportuni server.
+Inoltre l'uso di diversi supporti possibili per le stesse informazioni (ad
+esempio il nome delle macchine può essere mantenuto sia tramite
+\file{/etc/hosts}, che con il DNS, che con NIS) comporta il problema
dell'ordine in cui questi vengono interrogati.\footnote{con le implementazioni
classiche i vari supporti erano introdotti modificando direttamente le
funzioni di liberia, prevedendo un ordine di interrogazione predefinito e
generiche di libreria usate anche dal sistema del \textit{resolver}.
Il sistema del DNS è in sostanza di un database distribuito organizzato in
-maniera gerarchica, la manutenzione dei dati è mantenuta in tanti server
-distinti ciascuno dei quali si occupa della risoluzione del proprio
-\textsl{dominio}; i nomi a dominio sono poi organizzati in una struttura ad
-albero analoga a quella dell'albero dei file in un sistema unix-like, 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. 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 contiene comunque una serie di altre informazioni;
-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. Oggigiorno i dati
-mantenuti nei server DNS sono sostanzialmente relativi soltanto ad indirizzi
-internet, per cui in pratica c'è soltanto una classe di indirizzi utilizzata,
-i dati invece possono essere di vario tipo, uno dei quali è appunto la
-corrispondenza fra nome a dominio e numero IP.
-
-L'esistenza di vari tipi di informazioni ottenibili da un server DNS è
-un'altro dei motivi per cui il \textit{resolver} prevede un insieme di
-funzioni dedicato rispetto a quelle della semplice risoluzione dei nomi; la
-prima di queste è \funcd{res\_init}, il cui prototipo è:
+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. Oggigiorno i dati mantenuti nei server DNS sono
+sostanzialmente relativi soltanto ad indirizzi internet, per cui in pratica
+c'è soltanto una classe di indirizzi utilizzata, i dati invece possono essere
+di vario tipo, uno dei quali è appunto la corrispondenza fra nome a dominio e
+numero IP.
+
+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)}
+ \headdecl{netinet/in.h} \headdecl{arpa/nameser.h} \headdecl{resolv.h}
+ \funcdecl{int res\_init(void)}
Inizializza il sistema del \textit{resolver}.
errore.}
\end{functions}
-La funzione legge il contenuto dei file di configurazione 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. In genere si deve eseguire questa funzione prima di
-chiamare tutte le altre.
+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 è necessario eseguire questa
+funzione direttamente in quanto viene automaticamente chiamata la prima che si
+esegue una delle altre.
Le impostazioni del resolver e lo stato del sistema vengono mantenute in una
-serie di variabili globali contenuti in una apposita struttura interna,
-definita in \file{resolv.h}, che può essere acceduta una volta che la si
-dichiara con:
-\includecodesnip{listati/resolv_option.c}
-
-Tutti i campi della struttura sono ad uso interno, l'unico che può essere
-utile modificare è il campo \var{\_res.options}, che è una maschera binaria
-che permette di controllare il comportamento del resolver, modificandone
-alcune impostazioni direttamente da programma prima di invocare
-\func{res\_init}. Le costanti che definiscono i vari bit di questo campo, con
-il relativo significato sono illustrate in tab.~\ref{tab:resolver_option}, un
-valore deve essere espresso con un opportuno OR aritmetico di dette costanti;
-ad esempio il valore di default dato dalla costante \const{RES\_DEFAULT} è
-definito come:
-\includecodesnip{listati/resolv_option_def.c}
+serie di variabili contenute in una apposita struttura interna che viene
+definita in \file{resolv.h} ed è utilizzata come variabile globale, così che
+anche un programma vi può accedure una volta che essa sia stata 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 resolver.
\begin{table}[htb]
\centering
\label{tab:resolver_option}
\end{table}
-La funzione di richiesta principale è \funcd{res\_query}, che serve ad
-eseguire una richiesta ad un server DNS per un nome a dominio completamente
-specificato (quello che si chiama FQDN, \textit{Fully Qualified Domain Name});
-il suo prototipo è:
+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}
Esegue una interrogazione al DNS.
-\bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
- errore.}
+\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.
+
-Per quanto ci interessa i tipi di \textit{resource record} che vengono
-utilizzati dal \textit{resolver} sono sostanzialmente i seguenti:
+Una seconda funzione di ricerca, analoga a \func{res\_query}, e che prende gli
+stessi argomenti, ma 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 opportunamente il dominio di default da cercare nella stinga
+\param{dname}, 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 capitolo 14 di
+\cite{DNSbind}.
+
+Le classi di indirizzi supportate da un server DNS sono tre, ma di queste in
+pratica oggi viene utilizzata solo quella degli indirizzi internet; le
+costanti che identificano dette classi come valore per l'argomento
+\param{class} 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 DNS sono
+diverse, ed a ciascuna di essa corriponde ad un diverso tipo di
+\textit{resource record}; l'elenco dei valori possibili\footnote{come
+ ottenibile dai file di dichiarazione \file{arpa/nameser.h} e
+ \file{arpa/nameser_compat.h}.} che si possono indicare per l'argomento
+\param{type} è riportato in tab.~\ref{tab:DNS_record_type}; le costanti (tolto
+il \texttt{T\_} iniziale) usano gli stessi valori usati per identificare i
+record nei file di zona di BIND, e che normalmente sono anche usati come
+\textsl{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} & trasferimenzo di zona di autorità.\\
+ \const{T\_MAILB} & trasferimento di record di caselle di posta.\\
+ \const{T\_MAILA} & trasferimetno 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, pertanto non entreremo nei dettagli del
+significato di tutti quanti, ma solo di quelli usati dalle funzioni del
+\textit{resolver}, che sono sostanzialmente i seguenti:
\begin{basedescript}{\desclabelwidth{1.2cm}\desclabelstyle{\nextlinelabel}}
-\item[\texttt{A}] indica la corripondenza fra un nome a dominio ed un
+\item[\texttt{A}] 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}] chiamato in questo modo dato che la dimensione è quattro
- volte quella di un indirizzo IPv4, questo record contiene la corrispondenza
- fra un nome a dominio ed un indirizzo IPv6.
+\item[\texttt{AAAA}] 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 provvedere la mappatura inversa fra un indirizzo IP ed
- un nome a dominio si utilizza invece questo tipo di record (il cui nome sta
- per \textit{pointer}).
-\item[\texttt{CNAME}] qualora si abbiamo più nomi con i quali si voglia
- indicare lo stesso indirizzo (ad esempio \texttt{www.truelite.it}, o
- \texttt{sources.truelite.it}, che comunque fanno sempre riferimento alla
- macchina \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
+ un nome a dominio 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 (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, a
+differenza delle funzioni viste finora, 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, e può non avere
+nessun significato nell'indicare quale parte del procedimento di risoluzione è
+fallita.
+Per questo motivo all'interno del resolver è stata definita una apposita
+variabile di errore, \var{h\_errno} che viene utilizzata dalle funzioni del
+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 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},
+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 e come per 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}).
-Per questo motivo il \textit{resolver} prevede delle funzioni che permettono
-sia di eseguire direttamente delle interrogazione ad un server DNS, che di
-controllare le modalità con cui queste vengono eseguite; diventa così
-possibile modificare da programma buona parte dei parametri controllati da
-\file{/etc/resolv.conf}.
\subsection{La risoluzione dei nomi a dominio}
\label{sec:sock_gethostbyname}
-Dato che la principale funzionalità del \textit{resolver} resta quella di
-risolvere i nomi a dominio in indirizzi IP, vedremo per prime le funzioni a
-questo dedicate. La prima funzione è \funcd{gethostbyname} il cui scopo è
-ottenere l'indirizzo di una stazione noto il suo nome a dominio, il suo
-prototipo è:
+La principale funzionalità del \textit{resolver} resta quella di risolvere i
+nomi a dominio in indirizzi IP, per cui non ci dedicheremo oltre alle funzioni
+di richiesta generica ed esamineremo invece le funzioni a questo dedicate. La
+prima funzione è \funcd{gethostbyname} il cui scopo è ottenere l'indirizzo di
+una stazione noto il suo nome a dominio, il suo prototipo è:
\begin{prototype}{netdb.h}
{struct hostent *gethostbyname(const char *name)}
La funzione prende come argomento una stringa \param{name} contenente il nome
a dominio che si vuole risolvere, in caso di successo i dati ad esso relativi
vengono memorizzati in una opportuna struttura \struct{hostent} la cui
-definizione è riportata in fig.~\ref{fig:sock_hostent_struct}. In caso di
-insuccesso l'errore viene segnalato da un valore nullo del puntatore, ma in
-questo caso, a differenza delle funzioni viste finora, non viene utilizzata la
-variabile \var{errno} per riportare un codice di errore, in quanto questo
-dipende solo dalle sottostanti chiamate al sistema e può non avere nessun
-significato nell'indicare quale parte del procedimento di risoluzione è
-fallita.
+definizione è riportata in fig.~\ref{fig:sock_hostent_struct}.
\begin{figure}[!htb]
\footnotesize \centering
\label{fig:sock_hostent_struct}
\end{figure}
-Per questo motivo all'interno del resolver è stata definita una apposita
-variabile di errore, \var{h\_errno} che viene utilizzata dalle funzioni di
-libreria 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 sono i seguenti:
-\begin{basedescript}{\desclabelwidth{3cm}\desclabelstyle{\nextlinelabel}}
-\item[\const{HOST\_NOT\_FOUND}] l'indirizzo richiesto non è valido e la
- macchina indicata è sconosciuta.
-\item[\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}).
-\item[\const{NO\_RECOVERY}] si è avuto un errore non recuperabile
- nell'interrogazione di un server DNS.
-\item[\const{TRY\_AGAIN}] si è avuto un errore temporaneo nell'interrogazione
- di un server DNS, si può ritentare l'interrogazione in un secondo tempo.
-\end{basedescript}
-
Quando un programma chiama \func{gethostbyname} e questa usa il DNS per
-effettuare la risoluzione del nome, è con i valori di questi record che
-vengono riempite le varie parti della struttura \struct{hostent}. Il primo
-campo della struttura, \var{h\_name} contiene sempre il \textsl{nome
+effettuare la risoluzione del nome, è con i valori contenuti nei relativi
+record che vengono riempite le varie parti della struttura \struct{hostent}.
+Il primo campo della struttura, \var{h\_name} contiene sempre il \textsl{nome
canonico}, che nel caso del DNS è appunto il nome associato ad un record
\texttt{A}. Il secondo campo della struttura, \var{h\_aliases}, invece è un
puntatore ad vettore di puntatori, terminato da un puntatore nullo. Ciascun
Il terzo campo della struttura, \var{h\_addrtype}, indica il tipo di indirizzo
che è stato restituito, e può assumere soltanto i valori \const{AF\_INET} o
\const{AF\_INET6}, mentre il quarto campo, \var{h\_length}, indica la
-lunghezza dell'indirizzo stesso in byte. La funzione ritorna sempre una
-struttura
+lunghezza dell'indirizzo stesso in byte.
Infine il campo \var{h\_addr\_list} è il puntatore ad un vettore di puntatori
ai singoli indirizzi; il vettore è terminato da un puntatore nullo. Inoltre,
\code{h\_addr\_list[0]}.
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{15cm}
+ \includecodesample{listati/myhost.c}
+ \end{minipage}
+ \normalsize
+ \caption{Esempio di codice per la risoluzione di un indirizzo.}
+ \label{fig:myhost_example}
+\end{figure}
+
+Vediamo allora un primo esempio dell'uso di queste funzioni, in
+fig.~\ref{fig:myhost_example} è riportato un estratto del codice di un
+programma che esegue una semplice interrogazione al resolver usando
+\func{gethostbyname} e stampa a video i risultati. Al solito il sorgente
+completo, he comprende il trattamento delle opzioni ed una funzione per
+stampare un messaggio di aiuto, è nel file \texttt{myhost.c} dei sorgenti
+allegati alla guida.
+
+
+
+Con l'uso di \func{gethostbyname} normalmente si ottengono solo gli indirizzi
+IPv4, se si vogliono ottenere degli indirizzi IPv6 occorrerà prima impostare
+l'opzione \const{RES\_USE\_INET6} nel campo \texttt{\_res.options} e chiamare
+\func{res\_init} (vedi sez.~\ref{sec:sock_resolver_functions}) per modificare
+le opzioni del resolver; dato che questo non è molto comodo è stata definita
+un'altra funzione, \funcd{gethostbyname2}, il cui prototipo è:
+\begin{prototype}{netdb.h}
+{struct hostent *gethostbyname2(const char *name, int af)}
+
+Determina l'indirizzo di tipo \param{af} associato al nome a dominio
+\param{name}.
+
+\bodydesc{La funzione restituisce in caso di successo il puntatore ad una
+ struttura di tipo \struct{hostent} contente i dati associati al nome a
+ dominio o un puntatore nullo in caso di errore.}
+\end{prototype}
+In questo caso la funzione prende un secondo argomento \param{af} che indica
+la famiglia di indirizzi da usare come
l'altro capo è stato chiuso, e quindi non sarà più possibile leggere niente) e
pertanto si ritorna senza aver concluso la lettura di tutti i byte
richiesti. Entrambe le funzioni restituiscono 0 in caso di successo, ed un
-valore negativo in caso di errore, \texttt{FullRead} restituisce il numero di
+valore negativo in caso di errore, \func{FullRead} restituisce il numero di
byte non letti in caso di end-of-file prematuro.
l'ora locale della macchina a cui si effettua la richiesta, e che è assegnato
alla porta 13.
-In fig.~\ref{fig:TCP_daytime_client_code} è riportata la sezione principale del
-codice del nostro client. Il sorgente completo del programma
-(\file{TCP\_daytime.c}, che comprende il trattamento delle opzioni ed una
+In fig.~\ref{fig:TCP_daytime_client_code} è riportata la sezione principale
+del codice del nostro client. Il sorgente completo del programma
+(\texttt{TCP\_daytime.c}, che comprende il trattamento delle opzioni ed una
funzione per stampare un messaggio di aiuto) è allegato alla guida nella
sezione dei codici sorgente e può essere compilato su una qualunque macchina
GNU/Linux.
primo esempio realizzeremo un server iterativo, in grado di fornire una sola
risposta alla volta. Il codice del programma è nuovamente mostrato in
fig.~\ref{fig:TCP_daytime_iter_server_code}, il sorgente completo
-(\file{TCP\_iter\_daytimed.c}) è allegato insieme agli altri file degli esempi.
+(\texttt{TCP\_iter\_daytimed.c}) è allegato insieme agli altri file degli
+esempi.
\begin{figure}[!htbp]
\footnotesize \centering
codice, in cui si sono tralasciati il trattamento delle opzioni e le parti
rimaste invariate rispetto al precedente esempio (cioè tutta la parte
riguardante l'apertura passiva del socket). Al solito il sorgente completo del
-server, nel file \file{TCP\_cunc\_daytimed.c}, è allegato insieme ai sorgenti
-degli altri esempi.
+server, nel file \texttt{TCP\_cunc\_daytimed.c}, è allegato insieme ai
+sorgenti degli altri esempi.
\begin{figure}[!htb]
\footnotesize \centering
\label{sec:TCP_echo_client}
Il codice della prima versione del client per il servizio \textit{echo},
-disponibile nel file \file{TCP\_echo\_first.c}, è riportato in
+disponibile nel file \texttt{TCP\_echo\_first.c}, è riportato in
fig.~\ref{fig:TCP_echo_client_1}. Esso ricalca la struttura del precedente
client per il servizio \textit{daytime} (vedi
-sez.~\ref{sec:TCP_daytime_client}), e la prima parte (\texttt{\small 10--27}) è
-sostanzialmente identica, a parte l'uso di una porta diversa.
+sez.~\ref{sec:TCP_daytime_client}), e la prima parte (\texttt{\small 10--27})
+è sostanzialmente identica, a parte l'uso di una porta diversa.
\begin{figure}[!htb]
\footnotesize \centering
\subsection{Il server \textit{echo}: prima versione}
\label{sec:TCPsimp_server_main}
-La prima versione del server, contenuta nel file \file{TCP\_echod\_first.c}, è
-riportata in fig.~\ref{fig:TCP_echo_server_first_code}. Come abbiamo fatto per
-il client anche il server è stato diviso in un corpo principale, costituito
-dalla funzione \code{main}, che è molto simile a quello visto nel precedente
-esempio per il server del servizio \textit{daytime} di
+La prima versione del server, contenuta nel file \texttt{TCP\_echod\_first.c},
+è riportata in fig.~\ref{fig:TCP_echo_server_first_code}. Come abbiamo fatto
+per il client anche il server è stato diviso in un corpo principale,
+costituito dalla funzione \code{main}, che è molto simile a quello visto nel
+precedente esempio per il server del servizio \textit{daytime} di
sez.~\ref{sec:TCP_daytime_cunc_server}, e da una funzione ausiliaria
\code{ServEcho} che si cura della gestione del servizio.
introdotte una serie di nuove opzioni che ci saranno utili per il debug, è
mostrata in fig.~\ref{fig:TCP_echo_server_code_second}, dove si sono riportate
la sezioni di codice modificate nella seconda versione del programma, il
-codice completo di quest'ultimo si trova nel file \file{TCP\_echod\_second.c}
-dei sorgenti allegati alla guida.
+codice completo di quest'ultimo si trova nel file
+\texttt{TCP\_echod\_second.c} dei sorgenti allegati alla guida.
La prima modifica effettuata è stata quella di introdurre una nuova opzione a
riga di comando, \texttt{-c}, che permette di richiedere il comportamento
\label{fig:TCP_ClientEcho}
\end{figure}
-Si è allora riportato in fig.~\ref{fig:TCP_ClientEcho} la versione finale della
-nostra funzione \func{ClientEcho}, in grado di gestire correttamente l'intero
-flusso di dati fra client e server. Il codice completo del client,
+Si è allora riportato in fig.~\ref{fig:TCP_ClientEcho} la versione finale
+della nostra funzione \func{ClientEcho}, in grado di gestire correttamente
+l'intero flusso di dati fra client e server. Il codice completo del client,
comprendente la gestione delle opzioni a riga di comando e le istruzioni per
-la creazione della connessione, si trova nel file \file{TCP\_echo.c},
+la creazione della connessione, si trova nel file \texttt{TCP\_echo.c},
distribuito coi sorgenti allegati alla guida.
La nuova versione è molto simile alla precedente di
In fig.~\ref{fig:TCP_PollEchod} è riportata la sezione principale della nuova
versione del server, la versione completa del codice è riportata nel file
-\file{poll\_echod.c} dei sorgenti allegati alla guida. Al solito nella figura
-si sono tralasciate la gestione delle opzioni, la creazione del socket in
-ascolto, la cessione dei privilegi e le operazioni necessarie a far funzionare
-il programma come demone, privilegiando la sezione principale del programma.
+\texttt{poll\_echod.c} dei sorgenti allegati alla guida. Al solito nella
+figura si sono tralasciate la gestione delle opzioni, la creazione del socket
+in ascolto, la cessione dei privilegi e le operazioni necessarie a far
+funzionare il programma come demone, privilegiando la sezione principale del
+programma.
Come per il precedente server basato su \func{select} il primo passo
(\texttt{\small 2--8}) è quello di inizializzare le variabili necessarie. Dato