ALcune correzioni sparse, risistemati i commenti interni delle varie
[gapil.git] / sockctrl.tex
index dbe5af3b1c056293f8ab5b8589cb36c67466bb11..62fd3d7037692a521a027423fa3d9f40f293cf9a 100644 (file)
@@ -705,20 +705,20 @@ suoi risultati.
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
-    \includecodesample{listati/myhost.c}
+    \includecodesample{listati/mygethost.c}
   \end{minipage}
   \normalsize
   \caption{Esempio di codice per la risoluzione di un indirizzo.}
-  \label{fig:myhost_example}
+  \label{fig:mygethost_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
+fig.~\ref{fig:mygethost_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, che comprende il trattamento delle opzioni ed una funzione
-per stampare un messaggio di aiuto, è nel file \texttt{myhost.c} dei sorgenti
-allegati alla guida.
+per stampare un messaggio di aiuto, è nel file \texttt{mygethost.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
@@ -1199,16 +1199,18 @@ forniscono una interfaccia sufficientemente generica.
 Inoltre in genere quando si ha a che fare con i socket non esiste soltanto il
 problema della risoluzione del nome che identifica la macchina, ma anche
 quello del servizio a cui ci si vuole rivolgere.  Per questo motivo con lo
-standard Posix 1003.1-2001 sono state indicate come deprecate le varie
+standard POSIX 1003.1-2001 sono state indicate come deprecate le varie
 funzioni \func{gethostbyaddr}, \func{gethostbyname}, \var{getipnodebyname} e
 \var{getipnodebyaddr} ed è stata introdotta una interfaccia completamente
 nuova.
 
-La prima funzione di questa interfaccia, che combina le funzionalità di
-\func{getipnodebyname}, \func{getipnodebyaddr}, \func{getservbyname} e
-\func{getservbyport}, consentendo di ottenere contemporaneamente la
-risoluzione di un indirizzo e di un servizio, è \funcd{getaddrinfo}, il cui
-prototipo è:
+La prima funzione di questa interfaccia è \funcd{getaddrinfo},\footnote{la
+  funzione è definita, insieme a \func{getnameinfo} che vedremo più avanti,
+  nell'\href{http://www.ietf.org/rfc/rfc2553.txt} {RFC~2553}.} che combina le
+funzionalità delle precedenti \func{getipnodebyname}, \func{getipnodebyaddr},
+\func{getservbyname} e \func{getservbyport}, consentendo di ottenere
+contemporaneamente sia la risoluzione di un indirizzo simbolico che del nome
+di un servizio; il suo prototipo è:
 \begin{functions}
   \headdecl{netdb.h} 
   \headdecl{sys/socket.h} 
@@ -1224,13 +1226,438 @@ prototipo 
 \end{functions}
 
 La funzione prende come primo argomento il nome della macchina che si vuole
-risolvere. Questo, oltre ad un comune nome a dominio, può essere anche un
-indirizzo numerico in forma \textit{dotted-decimal} per IPv4 o in formato
-esadecimale per IPv6.  Si può anche specificare il nome di una rete invece che
-di una singola macchina. Il secondo argomento specifica invece il nome del
-servizio che si intende risolvere. Uno di questi due argomenti può essere
-anche inizializzato a \const{NULL}
+risolvere, specificato tramite la stringa \param{node}. Questo argomento,
+oltre ad un comune nome a dominio, può indicare anche un indirizzo numerico in
+forma \textit{dotted-decimal} per IPv4 o in formato esadecimale per IPv6.  Si
+può anche specificare il nome di una rete invece che di una singola macchina.
+Il secondo argomento, \param{service}, specifica invece il nome del servizio
+che si intende risolvere. Per uno dei due argomenti si può anche usare il
+valore \const{NULL}, nel qual caso la risoluzione verrà effettuata soltanto
+sulla base del valore dell'altro.
+
+Il terzo argomento, \param{hints}, deve essere invece un puntatore ad una
+struttura \struct{addrinfo} usata per dare dei \textsl{suggerimenti} al
+procedimento di risoluzione riguardo al protocollo o del tipo di socket che si
+intenderà utilizzare; \func{getaddrinfo} infatti permette di effettuare
+ricerche generiche sugli indirizzi, usando sia IPv4 che IPv6, e richiedere
+risoluzioni sui nomi dei servizi indipendentemente dal protocollo (ad esempio
+TCP o UDP) che questi possono utilizzare.
 
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \includestruct{listati/addrinfo.h}
+  \end{minipage}
+  \caption{La struttura \structd{addrinfo} usata nella nuova interfaccia POSIX
+    per la risoluzione di nomi a dominio e servizi.}
+  \label{fig:sock_addrinfo_struct}
+\end{figure}
+
+La struttura \struct{addrinfo}, la cui definizione\footnote{la definizione è
+  ripresa direttamente dal file \texttt{netdb.h} in questa struttura viene
+  dichiarata, la pagina di manuale riporta \type{size\_t} come tipo di dato
+  per il campo \var{ai\_addrlen}, qui viene usata quanto previsto dallo
+  standard POSIX, in cui viene utilizzato \type{socklen\_t}; i due tipi di
+  dati sono comunque equivalenti.} è riportata in
+fig.~\ref{fig:sock_addrinfo_struct}, viene usata sia in ingresso, per passare
+dei valori di controllo alla funzione, che in uscita, per ricevere i
+risultati. Il primo campo, \var{ai\_flags}, è una maschera binaria di bit che
+permettono di controllare le varie modalità di risoluzione degli indirizzi,
+che viene usato soltanto in ingresso. I tre campi successivi \var{ai\_family},
+\var{ai\_socktype}, e \var{ai\_protocol} contengono rispettivamente la
+famiglia di indirizzi, il tipo di socket e il protocollo, in ingresso vengono
+usati per impostare una selezione (impostandone il valore nella struttura
+puntata da \param{hints}), mentre in uscita indicano il tipo di risultato
+contenuto nella struttura. 
+
+Tutti i campi seguenti vengono usati soltanto in uscita; il campo
+\var{ai\_addrlen} indica la dimensione della struttura degli indirizzi
+ottenuta come risultato, il cui contenuto sarà memorizzato nella struttura
+\struct{sockaddr} posta all'indirizzo puntato dal campo \var{ai\_addr}. Il
+campo \var{ai\_canonname} è un puntatore alla stringa contenente il nome
+canonico della macchina, ed infine, quando la funzione restituisce più di un
+risultato, \var{ai\_next} è un puntatore alla successiva struttura
+\struct{addrinfo} della lista.
+
+Ovviamente non è necessario dare dei suggerimenti in ingresso, ed usando
+\const{NULL} come valore per l'argomento \param{hints} si possono compiere
+ricerche generiche.  Se però si specifica un valore non nullo questo deve
+puntare ad una struttura \struct{addrinfo} precedentemente allocata nella
+quale siano stati opportunamente impostati i valori dei campi
+\var{ai\_family}, \var{ai\_socktype}, \var{ai\_protocol} ed \var{ai\_flags}.
+
+I due campi \var{ai\_family} e \var{ai\_socktype} prendono gli stessi valori
+degli analoghi argomenti della funzione \func{socket}; in particolare per
+\var{ai\_family} si possono usare i valori di tab.~\ref{tab:net_pf_names} ma
+sono presi in considerazione solo \const{PF\_INET} e \const{PF\_INET6}, mentre
+se non si vuole specificare nessuna famiglia di indirizzi si può usare il
+valore \const{PF\_UNSPEC}.  Allo stesso modo per \var{ai\_socktype} si possono
+usare i valori illustrati in sez.~\ref{sec:sock_type} per indicare per quale
+tipo di socket si vuole risolvere il servizio indicato, anche se i soli
+significativi sono \const{SOCK\_STREAM} e \const{SOCK\_DGRAM}; in questo caso,
+se non si vuole effettuare nessuna risoluzione specifica, si potrà usare un
+valore nullo.
+
+Il campo \var{ai\_protocol} permette invece di effettuare la selezione dei
+risultati per il nome del servizio usando il numero identificativo del
+rispettivo protocollo di trasporto (i cui valori possibili sono riportati in
+\file{/etc/protocols}); di nuovo i due soli valori utilizzabili sono quelli
+relativi a UDP e TCP, o il valore nullo che indica di ignorare questo campo
+nella selezione.
+
+Infine l'ultimo campo è \var{ai\_flags}; che deve essere impostato come una
+maschera binaria; i bit di questa variabile infatti vengono usati per dare
+delle indicazioni sul tipo di risoluzione voluta, ed hanno valori analoghi a
+quelli visti in sez.~\ref{sec:sock_name_services} per \func{getipnodebyname};
+il valore di \var{ai\_flags} può essere impostata con un OR aritmetico delle
+costanti di tab.~\ref{tab:ai_flags_values}, ciascuna delle quali identifica un
+bit della maschera.
+
+\begin{table}[!htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|p{10cm}|}
+    \hline
+    \textbf{Costante} & \textbf{Significato} \\
+    \hline
+    \hline
+    \const{AI\_PASSIVE}    & viene utilizzato per ottenere un indirizzo in
+                             formato adatto per una successiva chiamata a
+                             \func{bind}. Se specificato quando si è usato 
+                             \const{NULL} come valore per \param{node} gli
+                             indirizzi restituiti saranno inizializzati al
+                             valore generico (\const{INADDR\_ANY} per IPv4 e
+                             \const{IN6ADDR\_ANY\_INIT} per IPv6), altrimenti
+                             verrà usato l'indirizzo dell'interfaccia di
+                             \textit{loopback}. Se invece non è impostato gli
+                             indirizzi verrano restituiti in formato adatto ad
+                             una chiamata a \func{connect} o \func{sendto}.\\
+    \const{AI\_CANONNAME}  & richiede la restituzione del nome canonico della
+                             macchina, che verrà salvato in una stringa il cui
+                             indirizzo sarà restituito nel campo
+                             \var{ai\_canonname} della prima struttura
+                             \struct{addrinfo} dei risultati. Se il nome
+                             canonico non è disponibile al suo posto
+                             viene restituita una copia di \param{node}. \\ 
+    \const{AI\_NUMERICHOST}& se impostato il nome della macchina specificato
+                             con \param{node} deve essere espresso in forma
+                             numerica, altrimenti sarà restituito un errore
+                             \const{EAI\_NONAME} (vedi
+                             tab.~\ref{tab:addrinfo_error_code}), in questo
+                             modo si evita ogni chiamata alle funzioni di
+                             risoluzione.\\ 
+    \const{AI\_V4MAPPED}   & stesso significato dell'analoga di
+                             tab.~\ref{tab:sock_getipnodebyname_flags}.\\  
+    \const{AI\_ALL}        & stesso significato dell'analoga di
+                             tab.~\ref{tab:sock_getipnodebyname_flags}.\\ 
+    \const{AI\_ADDRCONFIG} & stesso significato dell'analoga di
+                             tab.~\ref{tab:sock_getipnodebyname_flags}.\\ 
+    \hline
+  \end{tabular}
+  \caption{Costanti associate ai bit del campo \var{ai\_flags} della struttura 
+    \struct{addrinfo}.} 
+  \label{tab:ai_flags_values}
+\end{table}
+
+Come ultimo argomento di \func{getaddrinfo} deve essere passato un puntatore
+ad una variabile (di tipo puntatore ad una struttura \struct{addrinfo}) che
+verrà utilizzata dalla funzione per riportare (come \textit{value result
+  argument}) i propri risultati. La funzione infatti è rientrante, ed alloca
+autonomamente tutta la memoria necessaria in cui verranno riportati i
+risultati della risoluzione.  La funzione scriverà in \param{res} il puntatore
+iniziale ad una \textit{linked list} di strutture di tipo \struct{addrinfo}
+contenenti tutte le informazioni ottenute.
+
+La funzione restituisce un valore nullo in caso di successo, o un codice in
+caso di errore. I valori usati come codice di errore sono riportati in
+tab.~\ref{tab:addrinfo_error_code}; dato che la funzione utilizza altre
+funzioni e chiamate al sistema per ottenere il suo risultato in generale il
+valore di \var{errno} non è significativo, eccetto il caso in cui si sia
+ricevuto un errore di \const{EAI\_SYSTEM}, nel qual caso l'errore
+corrispondente è riportato tramite \var{errno}.
+
+\begin{table}[!htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|p{10cm}|}
+    \hline
+    \textbf{Costante} & \textbf{Significato} \\
+    \hline
+    \hline
+    \const{EAI\_FAMILY}  & la famiglia di indirizzi richiesta non è
+                           supportata. \\ 
+    \const{EAI\_SOCKTYPE}& il tipo di socket richiesto non è supportato. \\
+    \const{EAI\_BADFLAGS}& il campo \var{ai\_flags} contiene dei valori non
+                           validi. \\
+    \const{EAI\_NONAME}  & il nome a dominio o il servizio non sono noti,
+                           viene usato questo errore anche quando si specifica
+                           il valore \const{NULL} per entrambi gli argomenti
+                           \param{node} e \param{service}. \\
+    \const{EAI\_SERVICE} & il servizio richiesto non è disponibile per il tipo
+                           di socket richiesto, anche se può esistere per
+                           altri tipi di socket. \\
+    \const{EAI\_ADDRFAMILY}& la rete richiesta non ha nessun indirizzo di rete
+                           per la famiglia di indirizzi specificata. \\
+    \const{EAI\_NODATA}  & la macchina specificata esiste, ma non ha nessun
+                           indirizzo di rete definito. \\
+    \const{EAI\_MEMORY}  & è stato impossibile allocare la memoria necessaria
+                           alle operazioni. \\
+    \const{EAI\_FAIL}    & il DNS ha restituito un errore di risoluzione  
+                           permanente. \\
+    \const{EAI\_AGAIN}   & il DNS ha restituito un errore di risoluzione  
+                           temporaneo, si può ritentare in seguito. \\
+    \const{EAI\_SYSTEM}  & c'è stato un errore di sistema, si può controllare
+                           \var{errno} per i dettagli. \\
+%    \hline
+% estensioni GNU, trovarne la documentazione
+%    \const{EAI\_INPROGRESS}& richiesta in corso. \\
+%    \const{EAI\_CANCELED}& la richiesta è stata cancellata.\\
+%    \const{EAI\_NOTCANCELED}& la richiesta non è stata cancellata. \\
+%    \const{EAI\_ALLDONE} & tutte le richieste sono complete. \\
+%    \const{EAI\_INTR}    & richiesta interrotta. \\
+    \hline
+  \end{tabular}
+  \caption{Costanti associate ai valori dei codici di errore della funzione
+    \func{getaddrinfo}.} 
+  \label{tab:addrinfo_error_code}
+\end{table}
+
+Come per i codici di errore di \func{gethostbyname} anche in questo caso è
+fornita una apposita funzione, analoga di \func{strerror}, che consente di
+utilizzarli direttamente per stampare a video un messaggio esplicativo; la
+funzione è \func{gai\_strerror} ed il suo prototipo è:
+\begin{functions}
+  \headdecl{netdb.h} 
+
+  \funcdecl{const char *gai\_strerror(int errcode)}
+
+  Fornisce il messaggio corrispondente ad un errore di \func{getaddrinfo}.
+
+  \bodydesc{La funzione restituisce il puntatore alla stringa contenente il
+    messaggio di errore.}
+\end{functions}
+
+La funzione restituisce un puntatore alla stringa contenente il messaggio
+corrispondente dal codice di errore \param{errcode} ottenuto come valore di
+ritorno di \func{getaddrinfo}.  La stringa è allocata staticamente, ma essendo
+costante, ed accessibile in sola lettura, questo non comporta nessun problema
+di rientranza della funzione.
+
+Dato che ad un certo nome a dominio possono corrispondere più indirizzi IP
+(sia IPv4 che IPv6), e che un certo servizio può essere fornito su protocolli
+e tipi di socket diversi, in generale, a meno di non aver eseguito una
+selezione specifica attraverso l'uso di \param{hints}, si otterrà una diversa
+struttura \struct{addrinfo} per ciascuna possibilità.  Ad esempio se si
+richiede la risoluzione del servizio \textit{echo} per l'indirizzo
+\texttt{www.truelite.it}, e si imposta \const{AI\_CANONNAME} per avere anche
+la risoluzione del nome canonico, si avrà come risposta della funzione la
+lista illustrata in fig.~\ref{fig:sock_addrinfo_list}.
+
+\begin{figure}[!htb]
+  \centering
+  \includegraphics[width=10cm]{img/addrinfo_list}
+  \caption{La \textit{linked list} delle strutture \struct{addrinfo}
+    restituite da \func{getaddrinfo}.}
+  \label{fig:sock_addrinfo_list}
+\end{figure}
+
+Come primo esempio di uso di \func{getaddrinfo} vediamo un programma
+elementare di interrogazione del resolver basato questa funzione, il cui corpo
+principale è riportato in fig.~\ref{fig:mygetaddr_example}. Il codice completo
+del programma, compresa la gestione delle opzioni in cui è gestita l'eventuale
+inizializzazione dell'argomento \var{hints} per restringere le ricerche su
+protocolli, tipi di socket o famiglie di indirizzi, è disponibile nel file
+\texttt{mygetaddr.c} dei sorgenti allegati alla guida.
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \includecodesample{listati/mygetaddr.c}
+  \end{minipage}
+  \normalsize
+  \caption{Esempio di codice per la risoluzione di un indirizzo.}
+  \label{fig:mygetaddr_example}
+\end{figure}
+
+Il corpo principale inizia controllando (\texttt{\small 1--5}) il numero di
+argomenti passati, che devono essere sempre due, e corrispondere
+rispettivamente all'indirizzo ed al nome del servizio da risolvere. A questo
+segue la chiamata (\texttt{\small 7}) alla funzione \func{getaddrinfo}, ed il
+successivo controllo (\texttt{\small 8--11}) del suo corretto funzionamento,
+senza il quale si esce immediatamente stampando il relativo codice di errore.
+
+Se la funzione ha restituito un valore nullo il programma prosegue
+inizializzando (\texttt{\small 12}) il puntatore \var{ptr} che sarà usato nel
+sucessivo ciclo (\texttt{\small 14--35}) di scansione della lista delle
+strutture \struct{addrinfo} restituite dalla funzione. Prima di eseguire
+questa scansione (\texttt{\small 12}) viene stampato il valore del nome
+canonico che è presente solo nella prima struttura.
+
+La scansione viene ripetuta (\texttt{\small 14}) fintanto che si ha un
+puntatore valido. La selezione principale è fatta sul campo \var{ai\_family},
+che stabilisce a quale famiglia di indirizzi fa riferimento la struttura in
+esame. Le possibilità sono due, un indirizzo IPv4 o IPv6, se nessuna delle due
+si verifica si provvede (\texttt{\small 27--30}) a stampare un messaggio di
+errore ed uscire.\footnote{questa eventualità non dovrebbe mai verificarsi,
+  almeno fintanto che la funzione \func{getaddrinfo} lavora correttamente.}
+
+Per ciascuno delle due possibili famiglie di indirizzi si estraggono le
+informazioni che poi verranno stampate alla fine del ciclo (\texttt{\small
+  31--34}). Il primo caso esaminato (\texttt{\small 15--21}) è quello degli
+indirizzi IPv4, nel qual caso prima se ne stampa l'indentificazione
+(\texttt{\small 16}) poi si provvede a ricavare la struttura degli indirizzi
+(\texttt{\small 17}) indirizzata dal campo \var{ai\_addr}, eseguendo un
+opportuno casting del puntatore per poter estrarre da questa la porta
+(\texttt{\small 18}) e poi l'indirizzo (\texttt{\small 19}) che verrà
+convertito con una chiamata ad \func{inet\_ntop}.
+
+La stessa operazione (\texttt{\small 21--27}) viene ripetuta per gli indirizzi
+IPv6, usando la rispettiva struttura degli indirizzi. Si noti anche come in
+entrambi i casi per la chiamata a \func{inet\_ntop} si sia dovuto passare il
+puntatore al campo contenente l'indirizzo IP nella struttura puntata dal campo
+\var{ai\_addr}.\footnote{il meccanismo è complesso a causa del fatto che al
+  contrario di IPv4, in cui l'indirizzo IP può essere espresso con un semplice
+  numero intero, in IPv6 questo deve essere necessariamente fornito come
+  struttura, e pertanto anche se nella struttura puntata da \var{ai\_addr}
+  sono presenti direttamente i valori finali, per l'uso con \func{inet\_ntop}
+  occorre comunque passare un puntatore agli stessi (ed il costrutto
+  \code{\&addr6->sin6\_addr} è corretto in quanto l'operatore \texttt{->} ha
+  on questo caso precedenza su \texttt{\&}).}
+
+Una volta estratte dalla struttura \struct{addrinfo} tutte le informazioni
+relative alla risoluzione richiesta e stampati i relativi valori, l'ultimo
+passo (\texttt{\small 34}) è di estrarre da \var{ai\_next} l'indirizzo della
+eventuale successiva struttura presente nella lista e ripetere il ciclo, fin
+tanto che, completata la scansione, questo avrà un valore nullo e si potrà
+terminare (\texttt{\small 36}) il programma.
+
+Si tenga presente che \func{getaddrinfo} non garantisce nessun particolare
+ordinamento della lista delle strutture \struct{addrinfo} restituite, anche se
+usualmente i vari indirizzi IP (se ne è presente più di uno) sono forniti
+nello stesso ordine in cui vengono inviati dal server DNS. In particolare
+nulla garantisce che vengano forniti prima i dati relativi ai servizi di un
+determinato protocollo o tipo di socket, se ne sono presenti di diversi.  Se
+allora utilizziamo il nostro programma potremo verificare il risultato:
+\begin{verbatim}
+[piccardi@gont sources]$ ./mygetaddr -c  gapil.truelite.it echo
+Canonical name sources2.truelite.it
+IPv4 address:
+        Indirizzo 62.48.34.25
+        Protocollo 6
+        Porta 7
+IPv4 address:
+        Indirizzo 62.48.34.25
+        Protocollo 17
+        Porta 7
+\end{verbatim}
+%$
+
+Una volta estratti i risultati dalla \textit{linked list} puntata da
+\param{res} se questa non viene più utilizzata si dovrà avere cura di
+disallocare opportunamente tutta la memoria, per questo viene fornita
+l'apposita funzione \funcd{freeaddrinfo}, il cui prototipo è:
+\begin{functions}
+  \headdecl{netdb.h} 
+
+  \funcdecl{void freeaddrinfo(struct addrinfo *res)}
+
+  Libera la memoria allocata da una precedente chiamata a \func{getaddrinfo}.
+
+  \bodydesc{La funzione non restituisce nessun codice di errore.}
+\end{functions}
+
+La funzione prende come unico argomento il puntatore \param{res}, ottenuto da
+una precedente chiamata a \func{getaddrinfo}, e scandisce la lista delle
+strutture per liberare tutta la memoria allocata. Dato che la funzione non ha
+valori di ritorno deve essere posta molta cura nel passare un valore valido
+per \param{res}.
+
+Si tenga presente infine che se si copiano i risultati da una delle strutture
+\struct{addrinfo} restituite nella lista indicizzata da \param{res}, occorre
+avere cura di eseguire una \index{\textit{deep~copy}}\textit{deep copy} in cui
+si copiano anche tutti i dati presenti agli indirizzi contenuti nella
+struttura \struct{addrinfo}, perché una volta disallocati i dati con
+\func{freeaddrinfo} questi non sarebbero più disponibili. 
+
+Anche la nuova intefaccia definita da POSIX prevede una nuova funzione per
+eseguire la risoluzione inversa e determinare nomi di servizi e di dominio
+dati i rispettivi valori numerici. La funzione che sostituisce le varie
+\func{gethostbyname}, \func{geipnodebyname} e \func{getservname} è
+\funcd{getnameinfo}, ed il suo prototipo è:
+\begin{functions}
+  \headdecl{sys/socket.h}
+  \headdecl{netdb.h}
+
+  \funcdecl{int getnameinfo(const struct sockaddr *sa, socklen\_t salen, char
+    *host, size\_t hostlen, char *serv, size\_t servlen, int flags)}
+
+  Risolve il contenuto di una struttura degli indirizzi in maniera
+  indipendente dal protocollo.
+
+  \bodydesc{La funzione restituisce 0 in caso di successo e un codice di
+    errore diverso da zero altrimenti.}
+\end{functions}
+
+La principale caratteristica di \func{getnameinfo} è che la funzione è in
+grado di eseguire una risoluzione inversa in maniera indipendente dal
+protocollo; il suo primo argomento \param{sa} infatti è il puntatore ad una
+struttura degli indirizzi generica, che può contenere sia indirizzi IPv4 che
+IPv6, la cui dimensione deve comunque essere specificata con l'argomento
+\param{salen}. 
+
+I risultati della funzione saranno restituiti nelle due stringhe puntate da
+\param{host} e \param{serv}, che dovranno essere state precedentemente
+allocate per una lunghezza massima che deve essere specificata con gli altri
+due argomenti \param{hostlen} e \param{servlen}. Si può, quando non si è
+interessati ad uno dei due, passare il valore \const{NULL} come argomento,
+così che la corrispondente informazione non verrà richiesta. Infine l'ultimo
+argomento \param{flags} è una maschera binaria i cui bit consentono di
+impostare le modalità con cui viene eseguita la ricerca, e deve essere
+specificato attraverso l'OR aritmetico dei valori illustrati in
+tab.~\ref{tab:getnameinfo_flags}.
+
+\begin{table}[!htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|p{10cm}|}
+    \hline
+    \textbf{Costante} & \textbf{Significato} \\
+    \hline
+    \hline
+    \const{NI\_NOFQDN}     & richiede che venga restituita solo il nome della
+                             macchina all'interno del dominio al posto del
+                             nome completo (FQDN).\\
+    \const{NI\_NUMERICHOST}& richiede che venga restituita la forma numerica
+                             dell'indirizzo (questo succede sempre se il nome
+                             non può essere ottenuto).\\ 
+    \const{NI\_NAMEREQD}   & richiede la restituzione di un errore se il nome
+                             non può essere risolto.\\
+    \const{NI\_NUMERICSERV}& richiede che il servizio venga restituito in
+                             forma numerica (attraverso il numero di porta).\\
+    \const{NI\_DGRAM}      & richiede che venga restituito il nome del
+                             servizio su UDP invece che quello su TCP per quei
+                             pichi servizi (porte 512-214) che soni diversi
+                             nei due protocolli.\\
+    \hline
+  \end{tabular}
+  \caption{Costanti associate ai bit dell'argomento \param{flags} della  
+    funzione \func{getnameinfo}.} 
+  \label{tab:getnameinfo_flags}
+\end{table}
+
+La funzione ritorna zero in caso di successo, e scrive i propri risultati agli
+indirizzi indicati dagli argomenti \param{host} e \param{serv} come stringhe
+terminate dal carattere NUL, a meno che queste non debbano essere troncate
+qualora la loro dimensione ecceda quelle specificate dagli argomenti
+\param{hostlen} e \param{servlen}. Sono comunque definite le due costanti
+\const{NI\_MAXHOST} e \const{NI\_MAXSERV}\footnote{le due costanti sono
+  definite in \file{netdb.h} ed hanno rispettivamente il valore 1024 e 12.}
+che possono essere utilizzate come limiti massimi.  In caso di errore viene
+restituito invece un codice che assume gli stessi valori illustrati in
+tab.~\ref{tab:addrinfo_error_code}.
+
+A questo punto possiamo fornire degli esempi di utilizzo diretto della nuova
+interfaccia, adottandola per rendere i nostri client 
 
 
 \section{Le opzioni dei socket}
@@ -1240,7 +1667,7 @@ Finora abbiamo trattato i socket nel loro comportamento pi
 possibile attivare alcune modalità diverse di funzionamento degli stessi
 
 Dato che la maggior parte delle opzioni dei socket sono relative ai socket
-TCP, ed hanno poi significato analogo quando usate con altri socket, abbiamo
+ TCP, ed hanno poi significato analogo quando usate con altri socket, abbiamo
 preferito trattare l'argomento in generale in questa sezione piuttosto che nel
 capitolo dedicato alla trattazione generica dei socket.