Modifiche che manco sapevo di aver fatto
[gapil.git] / sockctrl.tex
index 1b99e53285a8c279410038e81450cd0e80414aa6..cda32f6e4fc8e04f70842358f0cb6c805b7c4bae 100644 (file)
@@ -86,12 +86,13 @@ dominio, e prevedeva solo l'utilizzo del DNS e del file statico
 \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
@@ -105,11 +106,11 @@ NIS,\footnote{il \textit{Network Information Service} 
   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
@@ -206,38 +207,45 @@ 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, 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.\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)}
+  \headdecl{netinet/in.h} \headdecl{arpa/nameser.h} \headdecl{resolv.h}
+  \funcdecl{int res\_init(void)}
 
 Inizializza il sistema del \textit{resolver}.
 
@@ -245,31 +253,30 @@ 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. 
-
-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:
+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, 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}
-
-
+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
@@ -320,70 +327,312 @@ definito come:
   \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}
 
 
-Per quanto ci interessa i tipi di \textit{resource record} che vengono
-utilizzati dal \textit{resolver} sono sostanzialmente i seguenti:
+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}] indica 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{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
-  \textsl{nome canonico} della macchina (quello associato al record
-  \texttt{A}).
+\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}).
 
-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)}
 
 Determina l'indirizzo 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.}
+  struttura di tipo \struct{hostent} contenente i dati associati al nome a
+  dominio, o un puntatore nullo in caso di errore.}
 \end{prototype}
 
 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
@@ -394,29 +643,10 @@ fallita.
   \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
@@ -427,8 +657,7 @@ DNS vengono inseriti come record di tipo \texttt{CNAME}).
 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,
@@ -438,14 +667,172 @@ diretto al primo indirizzo della lista.
 
 Oltre ai normali nomi a dominio la funzione accetta come argomento
 \param{name} anche indirizzi numerici, in formato dotted decimal per IPv4 o
-con la notazione illustrata in sez.~\ref{sec:IP_ipv6_notation}. In tal caso
-\func{gethostbyname} non eseguirà nessuna interrogazione remota, ma si
-limiterà a copiare la stringa nel campo \var{h\_name} ed a creare la
-corrispondente struttura \var{in\_addr} da indirizzara con
+con la notazione illustrata in sez.~\ref{sec:IP_ipv6_notation} per IPv6. In
+tal caso \func{gethostbyname} non eseguirà nessuna interrogazione remota, ma
+si limiterà a copiare la stringa nel campo \var{h\_name} ed a creare la
+corrispondente struttura \var{in\_addr} da indirizzare con
 \code{h\_addr\_list[0]}.
 
+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 poi
+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{functions}
+  \headdecl{netdb.h} 
+  \headdecl{sys/socket.h}
+  \funcdecl{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} contenente i dati associati al nome a
+  dominio, o un puntatore nullo in caso di errore.}
+\end{functions}
+
+In questo caso la funzione prende un secondo argomento \param{af} che indica
+(i soli valori consentiti sono \const{AF\_INET} o \const{AF\_INET6}, per
+questo è necessario l'uso di \texttt{sys/socket.h}) la famiglia di indirizzi
+che dovrà essere utilizzata nei risultati restituiti dalla funzione. Per tutto
+il resto la funzione è identica a \func{gethostbyname}, ed identici sono i
+suoi risultati.
+
+\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 delle funzioni di risoluzione, in
+fig.~\ref{fig:myhost_example} è riportato un estratto del codice di un
+programma che esegue una semplice interrogazione al \textit{resolver} usando
+\func{gethostbyname} e poi ne 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.
+
+Il programma richiede un solo argomento che specifichi il nome da cercare,
+senza il quale (\texttt{\small 12--15}) esce con un errore. Dopo di che
+(\texttt{\small 16}) si limita a chiamare \func{gethostbyname}, ricendo il
+risultato nel puntatore \var{data}. Questo (\texttt{\small 17--20}) viene
+controllato per rilevare eventuali errori, nel qual caso il programma esce
+dopo aver stampato un messaggio con \func{herror}. 
+
+Se invece la risoluzione è andata a buon fine si inizia (\texttt{\small 21})
+con lo stampare il nome canonico, dopo di che (\texttt{\small 22--26}) si
+stampano eventuali altri nomi. Per questo prima (\texttt{\small 22}) si prende
+il puntatore alla cima della lista che contiene i nomi e poi (\texttt{\small
+  23--26}) si esegue un ciclo che sarà ripetuto fin tanto che nella lista si
+troveranno dei puntatori validi\footnote{si ricordi che la lista viene
+  terminata da un puntatore nullo.} per le stringhe dei nomi; prima
+(\texttt{\small 24}) si stamperà la stringa e poi (\texttt{\small 25}) si
+provvederà ad incrementare il puntatore per passare al successivo elemento
+della lista.
+
+Una volta stampati i nomi si passerà a stampare gli indirizzi, il primo passo
+(\texttt{\small 27--34}) è allora quello di riconoscere il tipo di indirizzo
+sulla base del valore del campo \var{h\_addrtype}, stampandolo a video. Si è
+anche previsto di stampare un errore nel caso (che non dovrebbe mai accadere)
+di un indirizzo non valido.
+
+Infine (\texttt{\small 35--40}) si stamperanno i valori degli indirizzi, di
+nuovo (\texttt{\small 35}) si inizializzerà un puntatore alla cima della lista
+e si eseguirà un ciclo fintanto che questo punterà ad indirizzi validi in
+maniera analoga a quanto fatto in precedenza per i nomi a dominio. Si noti
+come, essendo il campo \var{h\_addr\_list} un puntatore ad strutture di
+indirizzi generiche, questo sia ancora di tipo \texttt{char **} e si possa
+riutilizzare lo stesso puntatore usato per i nomi.
+
+Per ciascun indirizzo valido si provvederà (\texttt{\small 37}) ad una
+conversione con la funzione \func{inet\_ntop} (vedi
+sez.~\ref{sec:sock_addr_func}) passandole gli opportuni argomenti, questa
+restituirà la stringa da stampare (\texttt{\small 38}) con il valore
+dell'indirizzo in \var{buffer}, che si è avuto la cura di dichiarare
+inizialmente (\texttt{\small 10}) con dimensioni adeguate; dato che la
+funzione è in grado di tenere conto automaticamente del tipo di indirizzo non
+ci sono precauzioni particolari da prendere.\footnote{volendo essere pignoli
+  si dovrebbe controllarne lo stato di uscita, lo si è tralasciato per non
+  appesantire il codice, dato che in caso di indirizzi non validi si sarebbe
+  avuto un errore con \func{gethostbyname}, ma si ricordi che la sicurezza non
+  è mai troppa.}
+
+Le funzioni illustrate finora hanno un difetto fondamentale, utilizzando una
+area di memoria interna per allocare il contenuto della struttura
+\struct{hostent} non possono essere rientranti. Per questo motivo ne sono
+state definite delle versioni alternative rientranti, al solito queste sono
+caratterizzate dall'avere un suffisso \texttt{\_r}, pertanto avremo le due
+funzioni \funcd{gethostbyname\_r} e \funcd{gethostbyname2\_r} i cui prototipi
+sono:
+\begin{functions}
+  \headdecl{netdb.h} 
+  \headdecl{sys/socket.h}
+  \funcdecl{int gethostbyname\_r(const char *name, struct hostent *ret, 
+    char *buf, size\_t buflen, struct hostent **result, int *h\_errnop)}
+  \funcdecl{int gethostbyname2\_r(const char *name, int af,
+         struct hostent *ret, char *buf, size\_t buflen, 
+         struct hostent **result, int *h\_errnop)}
+  
+  Versioni rientranti delle funzioni \func{gethostbyname} e
+  \func{gethostbyname2}. 
+       
+  \bodydesc{Le funzioni restituiscono 0 in caso di successo ed un valore
+    negativo in caso di errore.}
+\end{functions}
+
+Gli argomenti \param{name} (e \param{af} per \func{gethostbyname2}) hanno lo
+stesso significato visto in precedenza. Tutti gli altri argomenti hanno lo
+stesso significato per entrambe le funzioni. Per evitare l'uso di variabili
+globali si dovrà allocare preventivamente una struttura \struct{hostent} in
+cui ricevere il risultato, passandone l'indirizzo alla funzione nell'argomento
+\param{ret}.  Inoltre, dato che \struct{hostent} contiene solo dei puntatori,
+dovrà essere allocato anche un buffer in cui le funzioni possano scrivere
+tutti i dati del risultato dell'interrogazione, l'indirizzo e la lunghezza di
+questo buffer devono essere indicati con gli argomenti \param{buf} e
+\param{buflen}. 
+
+Gli ultimi due argomenti vengono utilizzati per avere indietro i risultati
+come \index{\textit{value~result~argument}}\textit{value result argument}, si
+deve specificare l'indirizzo della variabile su cui salvare il codice di
+errore con \param{h\_errnop} e quello su cui salvare il puntatatore che si
+userà per accedere i dati con \param{result}.
+
+In caso di successo entrambe le funzioni restituiscono un valore nullo,
+altrimenti restituiscono un codice di errore negativo e all'indirizzo puntato
+da \param{result} sarà salvato un puntatore nullo, mentre a quello puntato da
+\param{h\_errnop} sarà salvato il valore del codice di errore dato che per
+essere rientrante la funzione non può la variabile globale \var{h\_errno}. In
+questo caso il codice di errore, oltre ai valori di
+tab.~\ref{tab:h_errno_values} si può avere anche quello di \errcode{ERANGE}
+qualora il buffer allocato non sia sufficiente a contenere i dati, in tal caso
+si dovrà semplicemente ripetere l'esecuzione della funzione con un buffer di
+dimensione maggiore.
+
+Una delle caratteristiche delle interrogazioni al servizio DNS è che queste
+sono normalmente eseguite con il protocollo UDP, ci sono casi in cui si
+preferisce che vengano usate connessioni permanenti con il protocollo TCP. Per
+ottenere questo sono previste delle funzioni apposite; la prima è
+\funcd{sethostent}, il cui prototipo è:
+\begin{prototype}{netdb.h}
+{void sethostent(int stayopen)}
+
+Richiede l'uso di connessioni per le interrogazioni ad un server DNS.
+
+\bodydesc{La funzione non restituisce nulla.}
+\end{prototype}
+
+
 
+\subsection{Altre funzioni di gestione dei nomi}
+\label{sec:sock_name_services}
 
+Quelle illustrate nella sezione precedente sono le funzioni classiche per la
+risoluzione di nomi ed indirizzi IP, ma abbiamo già visto in