Spostato il vecchi myhost.c e creato nuovo programma mygetaddr per provare
[gapil.git] / sockctrl.tex
index 5ef2c7cc0ab160165a4d742fd3661294aba778c6..8f6e63426e0d2b8315e55254a127d735e033e96b 100644 (file)
@@ -24,11 +24,11 @@ comportamento.
 Negli esempi dei capitoli precedenti abbiamo sempre identificato le singole
 macchine attraverso indirizzi numerici, sfruttando al più le funzioni di
 conversione elementare illustrate in sez.~\ref{sec:sock_addr_func} che
-permettono di passare da un indirizzo espresso in forma dotted decimal ad un
-numero. Vedremo in questa sezione le funzioni utilizzate per poter utilizzare
-dei nomi simbolici al posto dei valori numerici, e viceversa quelle che
-permettono di ottenere i nomi simbolici associati ad indirizzi, porte o altre
-proprietà del sistema.
+permettono di passare da un indirizzo espresso in forma \textit{dotted
+  decimal} ad un numero. Vedremo in questa sezione le funzioni utilizzate per
+poter utilizzare dei nomi simbolici al posto dei valori numerici, e viceversa
+quelle che permettono di ottenere i nomi simbolici associati ad indirizzi,
+porte o altre proprietà del sistema.
 
 
 \subsection{La struttura del \textit{resolver}}
@@ -64,17 +64,17 @@ con le librerie del C, detto appunto \textit{resolver}.
 Lo schema di funzionamento del \textit{resolver} è illustrato in
 fig.~\ref{fig:sock_resolver_schema}; in sostanza i programmi hanno a
 disposizione un insieme di funzioni di libreria con cui chiamano il
-\textit{resolver}, indicate con le freccie nere. Ricevuta la richiesta è
+\textit{resolver}, indicate con le frecce nere. Ricevuta la richiesta è
 quest'ultimo che, sulla base della sua configurazione, esegue le operazioni
 necessarie a fornire la risposta, che possono essere la lettura delle
 informazioni mantenute nei relativi dei file statici presenti sulla macchina,
 una interrogazione ad un DNS (che a sua volta, per il funzionamento del
-protocollo può interrogarene altri) o la richiesta ad altri server per i quali
+protocollo, può interrogarne altri) o la richiesta ad altri server per i quali
 sia fornito il supporto, come LDAP.\footnote{la sigla LDAP fa riferimento ad
   un protocollo, il \textit{Lightweight Directory Access Protocol}, che
   prevede un meccanismo per la gestione di \textsl{elenchi} di informazioni
   via rete; il contenuto di un elenco può essere assolutamente generico, e
-  questo permette il manenimento dei più vari tipi di informazioni su una
+  questo permette il mantenimento dei più vari tipi di informazioni su una
   infrastruttura di questo tipo.}
 
 La configurazione del \textit{resolver} attiene più alla amministrazione di
@@ -107,18 +107,18 @@ NIS,\footnote{il \textit{Network Information Service} 
   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, ma in una rete locale può essere molto
-utile centralizzare il mentenimento di alcune di esse su opportuni server.
+utile centralizzare il mantenimento 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
+  funzioni di libreria, prevedendo un ordine di interrogazione predefinito e
   non modificabile (a meno di una ricompilazione delle librerie stesse).}
 
 Per risolvere questa serie di problemi la risoluzione dei nomi a dominio
-eseguira dal \textit{resolver} è stata inclusa all'interno di un meccanismo
-generico per la risoluzione di corripondenze fra nomi ed informazioni ad essi
+eseguirà dal \textit{resolver} è stata inclusa all'interno di un meccanismo
+generico per la risoluzione di corrispondenze fra nomi ed informazioni ad essi
 associate chiamato \textit{Name Service Switch}\footnote{il sistema è stato
   introdotto la prima volta nelle librerie standard di Solaris, le \acr{glibc}
   hanno ripreso lo stesso schema, si tenga presente che questo sistema non
@@ -202,7 +202,7 @@ da esse utilizzato e cio
 benché in teoria sia solo uno dei possibili supporti su cui mantenere le
 informazioni, in pratica costituisce il meccanismo principale con cui vengono
 risolti i nomi a dominio.  Per questo motivo esistono una serie di funzioni di
-libreria che servono specificamente ad esseguire delle interrogazioni verso un
+libreria che servono specificamente ad eseguire delle interrogazioni verso un
 server DNS, funzioni che poi vengono utilizzate per realizzare le funzioni
 generiche di libreria usate anche dal sistema del \textit{resolver}.
 
@@ -238,7 +238,7 @@ 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
+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 è
@@ -302,7 +302,7 @@ comportamento del \textit{resolver}.
                               del dominio di default ai nomi singoli (che non
                               contengono cioè un ``\texttt{.}'').\\
     \const{RES\_STAYOPEN}   & usato con \const{RES\_USEVC} per mantenere
-                              aperte le connesioni TCP fra interrogazioni
+                              aperte le connessioni TCP fra interrogazioni
                               diverse. \\
     \const{RES\_DNSRCH}     & se attivo \func{res\_search} esegue le ricerche
                               di nomi di macchine nel dominio corrente o nei
@@ -334,7 +334,7 @@ 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
+esempio il valore di default delle opzioni, espresso dalla costante
 \const{RES\_DEFAULT}, è definito come:
 \includecodesnip{listati/resolv_option_def.c}
 
@@ -350,7 +350,7 @@ 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
+richiesta, ciascun tentativo di richiesta fallito viene ripetuto raddoppiando
 il tempo di scadenza per il numero massimo di volte stabilito da
 \texttt{RES\_RETRY}.
 
@@ -439,7 +439,7 @@ tab.~\ref{tab:DNS_address_class}.\footnote{esisteva in realt
 \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
+diverse, ed a ciascuna di essa corrisponde 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
@@ -448,7 +448,7 @@ 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
+  maggioranza dei casi, fa da riferimento; 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
@@ -468,7 +468,7 @@ e che normalmente sono anche usati come nomi per indicare i record.
     \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\_SOA}   & inizio 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.\\
@@ -489,7 +489,7 @@ e che normalmente sono anche usati come nomi per indicare i record.
     \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\_GPOS}  & posizione geografica.\\
     \const{T\_AAAA}  & indirizzo IPv6.\\
     \const{T\_LOC}   & informazione di collocazione.\\
     \const{T\_NXT}   & dominio successivo.\\
@@ -522,13 +522,13 @@ significato di tutti i \textit{resource record}, ma solo di quelli usati dalle
 funzioni del \textit{resolver}. Questi sono sostanzialmente i seguenti (per
 indicarli si è usata la notazione dei file di zona di BIND):
 \begin{basedescript}{\desclabelwidth{1.2cm}\desclabelstyle{\nextlinelabel}}
-\item[\texttt{A}] viene usato per indicare la corripondenza fra un nome a
+\item[\texttt{A}] viene usato per indicare la corrispondenza 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
+\item[\texttt{PTR}] per fornire la corrispondenza 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
@@ -602,9 +602,9 @@ funzione 
 \headdecl{netdb.h}
 \funcdecl{const char *hstrerror(int err)}
 
-Restituisce una stringa corripondente ad un errore di risoluzione.
+Restituisce una stringa corrispondente ad un errore di risoluzione.
 \end{functions}
-\noindent che, come  l'analoga \func{strerror}, restituise una stringa con un
+\noindent che, come  l'analoga \func{strerror}, restituisce una stringa con un
 messaggio di errore già formattato, corrispondente al codice passato come
 argomento (che si presume sia dato da \var{h\_errno}).
 
@@ -639,7 +639,8 @@ definizione 
   \begin{minipage}[c]{15cm}
     \includestruct{listati/hostent.h}
   \end{minipage}
-  \caption{La struttura \structd{hostent}.}
+  \caption{La struttura \structd{hostent} per la risoluzione dei nomi a
+    dominio e degli indirizzi IP.}
   \label{fig:sock_hostent_struct}
 \end{figure}
 
@@ -704,24 +705,24 @@ 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, 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.
+sorgente completo, che comprende il trattamento delle opzioni ed una funzione
+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
-(\texttt{\small 16}) si limita a chiamare \func{gethostbyname}, ricendo il
+(\texttt{\small 16}) si limita a chiamare \func{gethostbyname}, ricevendo 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}. 
@@ -816,7 +817,7 @@ 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 la funzione dovrà salvare
 il codice di errore con \param{h\_errnop} e quello su cui dovrà salvare il
-puntatatore che si userà per accedere i dati con \param{result}.
+puntatore 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
@@ -876,7 +877,7 @@ usare la funzione \funcd{gethostbyaddr}, il cui prototipo 
 \end{functions}
 
 In questo caso l'argomento \param{addr} dovrà essere il puntatore ad una
-appropriata struttura contentente il valore dell'indirizzo IP (o IPv6) che si
+appropriata struttura contenente il valore dell'indirizzo IP (o IPv6) che si
 vuole risolvere. L'uso del tipo \type{char *} per questo argomento è storico,
 il dato dovrà essere fornito in una struttura \struct{in\_addr}\footnote{si
   ricordi che, come illustrato in fig.~\ref{fig:sock_sa_ipv4_struct}, questo
@@ -900,7 +901,7 @@ dominio, la funziona comunque inizializza anche il primo campo della lista
 
 Per risolvere il problema dell'uso da parte delle due funzioni
 \func{gethostbyname} e \func{gethostbyaddr} di memoria statica che può essere
-socrascritta fra due chiamate successive, e per avere sempre la possibilità di
+sovrascritta fra due chiamate successive, e per avere sempre la possibilità di
 indicare esplicitamente il tipo di indirizzi voluto (cosa che non è possibile
 con \func{gethostbyname}), vennero introdotte due nuove funzioni di
 risoluzione,\footnote{le funzioni sono presenti nelle \acr{glibc} versione
@@ -929,11 +930,11 @@ cui prototipi sono:
 Entrambe le funzioni supportano esplicitamente la scelta di una famiglia di
 indirizzi con l'argomento \param{af} (che può assumere i valori
 \const{AF\_INET} o \const{AF\_INET6}), e restituiscono un codice di errore
-(identico a quelli precedentemente illustrati in
-tab.~\ref{tab:h_errno_values}) nella variabile puntata da
-\param{error\_num}. La funzione \func{getipnodebyaddr} richiede poi che si
-specifichi l'indirizzo come per \func{gethostbyaddr} passando anche la
-lunghezza dello stesso nell'argomento \param{len}.
+(con valori identici a quelli precedentemente illustrati in
+tab.~\ref{tab:h_errno_values}) nella variabile puntata da \param{error\_num}.
+La funzione \func{getipnodebyaddr} richiede poi che si specifichi l'indirizzo
+come per \func{gethostbyaddr} passando anche la lunghezza dello stesso
+nell'argomento \param{len}.
 
 La funzione \func{getipnodebyname} prende come primo argomento il nome da
 risolvere, inoltre prevede un apposito argomento \param{flags}, da usare come
@@ -972,13 +973,14 @@ tab.~\ref{tab:sock_getipnodebyname_flags}.
 \end{table}
 
 Entrambe le funzioni restituiscono un puntatore ad una struttura \var{hostent}
-allocata dinamicamente che contiene i risultati della ricerca, e per questo
-non soffrono dei problemi dovuti all'uso di una sezione statica di memoria
-presenti con le precedenti \func{gethostbyname} e \func{gethostbyaddr}.
-Questo però comporta la necessità di deallocare esplicitamente la memoria
-occupata dai risultati una volta che questi non siano più necessari, onde
-evitare perdite di memoria; a tale scopo viene fornita la funzione
-\funcd{freehostent}, il cui prototipo è:
+che contiene i risultati della ricerca, che viene allocata dinamicamente
+insieme a tutto lo spazio necessario a contenere i dati in essa referenziati;
+per questo motivo queste funzioni non soffrono dei problemi dovuti all'uso di
+una sezione statica di memoria presenti con le precedenti \func{gethostbyname}
+e \func{gethostbyaddr}.  L'uso di una allocazione dinamica però comporta anche
+la necessità di deallocare esplicitamente la memoria occupata dai risultati
+una volta che questi non siano più necessari; a tale scopo viene fornita la
+funzione \funcd{freehostent}, il cui prototipo è:
 \begin{functions}
   \headdecl{netdb.h} 
   \headdecl{sys/types.h} 
@@ -1008,9 +1010,9 @@ L'elenco di queste funzioni 
 tab.~\ref{tab:name_resolution_functions}, dove le si sono suddivise rispetto
 al tipo di informazione che forniscono (riportato in prima colonna). Nella
 tabella si è anche riportato il file su cui vengono ordinariamente mantenute
-queste informazioni, che può essere sostituito da un qualunque supporto
-interno al \textit{Name Service Switch}anche se usualmente questo avviene
-solo per la risoluzione degli indirizzi. Ciascuna funzione fa riferimento ad
+queste informazioni, che però può essere sostituito da un qualunque supporto
+interno al \textit{Name Service Switch} (anche se usualmente questo avviene
+solo per la risoluzione degli indirizzi). Ciascuna funzione fa riferimento ad
 una sua apposita struttura che contiene i relativi dati, riportata in terza
 colonna.
 
 una entità esterna; per le altre invece, estensioni fornite dal NSS a parte,
 si fa sempre riferimento ai dati mantenuti nei rispettivi file. 
 
-Consideriamo allora una ricerca sui nomi dei servizi, le due funzioni in
-questione sono \funcd{getservbyname} e \funcd{getservbyaddr} i cui prototopi
-sono:
+Dopo la risoluzione dei nomi a dominio una delle ricerche più comuni è quella
+sui nomi dei servizi noti (cioè \texttt{http}, \texttt{smtp}, ecc.) da
+associare alle rispettive porte, le due funzioni da utilizzare per questo sono
+\funcd{getservbyname} e \funcd{getservbyaddr}, che permettono rispettivamente
+di ottenere il numero di porta associato ad un servizio dato il nome e
+viceversa; i loro prototipi sono:
 \begin{functions}
   \headdecl{netdb.h} 
   \funcdecl{struct servent *getservbyname(const char *name, const char *proto)}
   \funcdecl{struct servent *getservbyport(int port, const char *proto)} 
 
-  Disalloca una struttura \var{hostent}.
+  Risolvono il nome di un servizio nel rispettivo numero di porta e viceversa.
        
-  \bodydesc{La funzione non ritorna nulla.}
+  \bodydesc{Ritornano il puntatore ad una struttura \struct{servent} con i
+    risultati in caso di successo, o \const{NULL} in caso di errore.}
 \end{functions}
 
+Entrambe le funzioni prendono come ultimo argomento una stringa \param{proto}
+che indica il protocollo per il quale si intende effettuare la
+ricerca,\footnote{le informazioni mantenute in \file{/etc/services} infatti
+  sono relative sia alle porte usate su UDP che su TCP, occorre quindi
+  specificare a quale dei due protocolli si fa riferimento.} che nel caso si
+IP può avere come valori possibili solo \texttt{udp} o
+\texttt{tcp};\footnote{in teoria si potrebbe avere un qualunque protocollo fra
+  quelli citati in \file{/etc/protocols}, posto che lo stesso supporti il
+  concetto di \textsl{porta}, in pratica questi due sono gli unici presenti.}
+se si specifica un puntatore nullo la ricerca sarà eseguita su un protocollo
+qualsiasi.
+
+Il primo argomento è il nome del servizio per \func{getservbyname},
+specificato tramite la stringa \param{name}, mentre \func{getservbyport}
+richiede il numero di porta in \param{port}. Entrambe le funzioni eseguono una
+ricerca sul file \file{/etc/services}\footnote{il \textit{Name Service Switch}
+  astrae il concetto a qualunque supporto su cui si possano mantenere i
+  suddetti dati. } ed estraggono i dati dalla prima riga che corrisponde agli
+argomenti specificati; se la risoluzione ha successo viene restituito un
+puntatore ad una apposita struttura \struct{servent} contenente tutti i
+risultati), altrimenti viene restituito un puntatore nullo.  Si tenga presente
+che anche in questo caso i dati vengono mantenuti in una area di memoria
+statica e che quindi la funzione non è rientrante.
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \includestruct{listati/servent.h}
+  \end{minipage}
+  \caption{La struttura \structd{servent} per la risoluzione dei nomi dei
+    servizi e dei numeri di porta.}
+  \label{fig:sock_servent_struct}
+\end{figure}
+
+La definizione della struttura \struct{servent} è riportata in
+fig.~\ref{fig:sock_servent_struct}, il primo campo, \var{s\_name} contiene
+sempre il nome canonico del servizio, mentre \var{s\_aliases} è un puntatore
+ad un vettore di stringhe contenenti gli eventuali nomi alternativi
+utilizzabili per identificare lo stesso servizio. Infine \var{s\_port}
+contiene il numero di porta e \var{s\_proto} il nome del protocollo.
+
+Come riportato in tab.~\ref{tab:name_resolution_functions} ci sono analoghe
+funzioni per la risoluzione del nome dei protocolli e delle reti; non staremo
+a descriverle nei dettagli, in quanto il loro uso è molto limitato, esse
+comunque hanno una struttura del tutto analoga alle precedenti, e tutti i
+dettagli relativi al loro funzionamento possono essere trovati nelle
+rispettive pagine di manuale.
+
+Oltre alle funzioni di ricerca esistono delle ulteriori funzioni che prevedono
+una lettura sequenziale delle informazioni mantenute nel \textit{Name Service
+  Switch} (in sostanza permettono di leggere i file contenenti le informazioni
+riga per riga), che sono analoghe a quelle elencate in
+tab.~\ref{tab:sys_passwd_func} per le informazioni relative ai dati degli
+utenti e dei gruppi.  Nel caso specifico dei servizi avremo allora le tre
+funzioni \funcd{setservent}, \funcd{getservent} e \funcd{endservent} i cui
+prototipi sono:
+\begin{functions}
+  \headdecl{netdb.h} 
+  \funcdecl{void setservent(int stayopen)} 
+  Apre il file \file{/etc/services} e si posiziona al suo inizio.
+
+  \funcdecl{struct servent *getservent(void)}
+  Legge la voce successiva nel file \file{/etc/services}.      
+
+  \funcdecl{void endservent(void)} 
+  Chiude il file \file{/etc/services}.
 
+  \bodydesc{Le due funzioni \func{setservent} e \func{endservent} non
+    restituiscono nulla, \func{getservent} restituisce il puntatore ad una
+    struttura \struct{servent} in caso di successo e \const{NULL} in caso di
+    errore o fine del file.}
+\end{functions}
 
-Oltre alle precedenti funzioni di ricerca sono definite anche delle ulteriori
-funzioni generiche che permettono di accedere direttamente al contenuto dei
-file contenenti le informazioni; come le precedenti esse sono tutte nella
-forma \texttt{setXXXent}, \texttt{getXXXent} ed \texttt{endXXXent}, e sono
-analoghe a quelle viste in sez.~\ref{sec:sys_user_group} per la lettura delle
-informazioni relative ai dati degli utenti e dei gruppi (vedi
-tab.~\ref{tab:sys_passwd_func}) che pure sono mantenute tremite il
-\textit{Name Service Switch}.
+La prima funzione, \func{getservent}, legge una singola voce a partire dalla
+posizione corrente in \file{/etc/services}, pertanto si può eseguire una
+lettura sequenziale dello stesso invocandola più volte. Se il file non è
+aperto provvede automaticamente ad aprirlo, nel qual caso leggerà la prima
+voce. La seconda funzione, \func{setservent}, permette di aprire il file
+\file{/etc/services} per una successiva lettura, ma se il file è già stato
+aperto riporta la posizione di lettura alla prima voce del file, in questo
+modo si può far ricominciare da capo una lettura sequenziale. L'argomento
+\param{stayopen}, se diverso da zero, fa sì che il file resti aperto anche fra
+diverse chiamate a \func{getservbyname} e \func{getservbyaddr}.\footnote{di
+  default dopo una chiamata a queste funzioni il file viene chiuso, cosicchè
+  una successiva chiamata a \func{getservent} riparte dall'inizio.}  La terza
+funzione, \funcd{endservent}, provvede semplicemente a chiudere il file.
+
+Queste tre funzioni per la lettura sequenziale di nuovo sono presenti per
+ciascuno dei vari tipi di informazione relative alle reti di
+tab.~\ref{tab:name_resolution_functions}; questo significa che esistono
+altrettante funzioni nella forma \texttt{setXXXent}, \texttt{getXXXent} e
+\texttt{endXXXent}, analoghe alle precedenti per la risoluzione dei servizi,
+che abbiamo riportato in tab.~\ref{tab:name_sequential_read}.  Essendo, a
+parte il tipo di informazione che viene trattato, sostanzialmente identiche
+nel funzionamento e di scarso utilizzo, non staremo a trattarle una per una,
+rimandando alle rispettive pagine di manuale.
 
+\begin{table}[!htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|l|l|l|}
+    \hline
+    \textbf{Informazione}&\multicolumn{3}{|c|}{\textbf{Funzioni}}\\
+    \hline
+    \hline
+    indirizzo&\func{sethostent}&\func{gethostent}&\func{endhostent} \\
+    servizio &cd te\func{setservent}&\func{getservent}&\func{endservent}\\ 
+    rete     &\func{setnetent}&\func{getnetent}&\func{endnetent}\\ 
+    protocollo&\func{setprotoent}&\func{getprotoent}&\func{endprotoent}\\ 
+    \hline
+  \end{tabular}
+  \caption{Funzioni lettura sequenziale dei dati del \textit{Name Service
+      Switch}.} 
+  \label{tab:name_sequential_read}
+\end{table}
 
 
 
@@ -1081,18 +1191,309 @@ risoluzione di nomi ed indirizzi IP, ma abbiamo gi
 di vari inconvenienti come il fatto che usano informazioni statiche, e non
 prevedono la possibilità di avere diverse classi di indirizzi. Anche se sono
 state create delle estensioni o metodi diversi che permettono di risolvere
-questi inconvenienti, non c'è comunque una interfaccia sufficientemente
-generica 
+alcuni di questi inconvenienti,\footnote{rimane ad esempio il problema
+  generico che si deve sapere in anticipo quale tipo di indirizzi IP (IPv4 o
+  IPv6) corrispondono ad un certo nome a dominio.}  comunque esse non
+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
+funzioni \func{gethostbyaddr}, \func{gethostbyname}, \var{getipnodebyname} e
+\var{getipnodebyaddr} ed è stata introdotta una interfaccia completamente
+nuova.
+
+La prima funzione di questa interfaccia è \funcd{getaddrinfo}, 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
+un servizio; il suo prototipo è:
+\begin{functions}
+  \headdecl{netdb.h} 
+  \headdecl{sys/socket.h} 
+  \headdecl{netdb.h} 
+
+  \funcdecl{int getaddrinfo(const char *node, const char *service, const
+    struct addrinfo *hints, struct addrinfo **res)}
+
+  Esegue una risoluzione di un nome a dominio e di un nome di servizio.
 
+  \bodydesc{La funzione restituisce 0 in caso di successo o un codice di
+    errore diverso da zero in caso di fallimento.}
+\end{functions}
 
-Per questo motivo lo standard Posix 1003.1-2001 indicava come deprecate le
-varie \func{gethostbyaddr}, \func{gethostbyname}, \var{getipnodebyname} e
-\var{getipnodebyaddr} per introdurre una interfaccia 
+La funzione prende come primo argomento il nome della macchina che si vuole
+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 utilizzando
+soltantoo 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; la funzione 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} è il puntatore alla stringa contenente il nome
+canonico della macchina, ed infine, quando la funzione restituisce più di un
+risultato, \var{ai\_next} è il puntatore alla struttura \struct{addrinfo}
+successiva 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 questo 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 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 restituire (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 restituisce in \param{res} il
+puntatore alla prima di 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 . \\
+    \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} si avrà come risposta 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.. Il codice
+del programma è 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:mygethost_example}
+\end{figure}
+
+
+
+Una volta estratti i risultati dalla \textit{linked list} puntata da
+\param{res} 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}.
 
-rimane comunque il problema generico che si deve sapere
-in anticipo quale tipo di indirizzi devo