Correzioni e revisione di ieri.
authorSimone Piccardi <piccardi@gnulinux.it>
Mon, 3 Apr 2017 13:02:16 +0000 (13:02 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Mon, 3 Apr 2017 13:02:16 +0000 (13:02 +0000)
listati/mygetaddr.c
sockctrl.tex
socket.tex
sources/mygetaddr.c

index 718b22995784dc7b58269aadd90233144e886840..c9401687c77f8ccf1ad904d0e349740beef44925 100644 (file)
     ptr = res;                                        /* init list pointer */
     printf("Canonical name %s\n", ptr->ai_canonname); /* print cname */
     while (ptr != NULL) {                             /* loop on list */
-       if (ptr->ai_family == PF_INET) {              /* if IPv4 */
+       if (ptr->ai_family == AF_INET) {              /* if IPv4 */
            printf("IPv4 address: \n");
            addr = (struct sockaddr_in *) ptr->ai_addr;     /* address */
            port = ntohs(addr->sin_port);                   /* port */
            string = inet_ntop(addr->sin_family, &addr->sin_addr, 
                               buffer, sizeof(buffer));
-       } else if (ptr->ai_family == PF_INET6) {      /* if IPv6 */
+       } else if (ptr->ai_family == AF_INET6) {      /* if IPv6 */
            printf("IPv6 address: \n");
            addr6 = (struct sockaddr_in6 *) ptr->ai_addr;   /* address */
            port = ntohs(addr6->sin6_port);                 /* port */
index 0364dd7732436b19f853386691c46c8433b16efe..1b8ee7b917a29f14d1befb29b3ab1513c877373d 100644 (file)
@@ -653,7 +653,7 @@ per \var{errno}, ma che usano il valore di \var{h\_errno}; la prima è
 }
 \end{funcbox}}
 
-La funzione è l'analoga di \func{perror} e stampa sullo standard error un
+La funzione è l'analoga di \func{perror} e stampa sullo \textit{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 è:
@@ -951,14 +951,17 @@ In questo caso l'argomento \param{addr} dovrà essere il puntatore ad una
 appropriata struttura contenente il valore dell'indirizzo IP (o IPv6) che si
 vuole risolvere. L'uso del tipo \texttt{char *} per questo argomento è
 storico, il dato dovrà essere fornito in una struttura \struct{in\_addr} per
-un indirizzo IPv4 ed una struttura \struct{in6\_addr} per un indirizzo IPv6;
-si ricordi che, come illustrato in fig.~\ref{fig:sock_sa_ipv4_struct}, che
-mentre \struct{in\_addr} in realtà corrisponde ad un numero intero, da
-esprimere comunque in \textit{network order}, non altrettanto avviene per
-\struct{in6\_addr}, pertanto è sempre opportuno inizializzare questi indirizzi
-con \func{inet\_pton} (vedi
-sez.~\ref{sec:sock_conv_func_gen}). Nell'argomento \param{len} se ne dovrà poi
-specificare la dimensione (rispettivamente 4 o 16), infine l'argomento
+un indirizzo IPv4 ed una struttura \struct{in6\_addr} per un indirizzo IPv6.
+
+Si ricordi inoltre, come illustrato in fig.~\ref{fig:sock_sa_ipv4_struct}, che
+mentre \struct{in\_addr} corrisponde in realtà ad un oridinario numero intero
+a 32 bit  (da esprimere comunque in \textit{network order}) non altrettanto
+avviene per \struct{in6\_addr}, pertanto è sempre opportuno inizializzare
+questi indirizzi con \func{inet\_pton} (vedi
+sez.~\ref{sec:sock_conv_func_gen}).
+
+Nell'argomento \param{len} se ne dovrà poi specificare la dimensione
+(rispettivamente 4 o 16), infine l'argomento
 \param{type} deve indicare il tipo di indirizzo, e dovrà essere o
 \const{AF\_INET} o \const{AF\_INET6}.
 
@@ -994,23 +997,52 @@ quelli già illustrati in per \func{gethostbyname\_r} e
 \func{gethostbyname2\_r} e devono essere usati allo stesso modo.
 
 Infine lo standard POSIX prevede la presenza della funzione
-\funcm{gethostent}, che dovrebbe ritornare la voce successiva nel database dei
-nomi a dominio, ma questo ha senso solo per la lettura dei dati da un file
-come \conffile{/etc/hosts} e non per i risultati del DNS. Nel caso della
-\acr{glibc} questa viene usata allora solo per la lettura di quest'ultimo,
-come avviene in altri sistemi, ed ignora le voci relative ad indirizzi
-IPv6. Dato che i risultati si possono ottenere in modo generico con le
-funzioni già illustrate, non la tratteremo esplicitamente, come non tratteremo
-la sua variante rientrante \funcm{gethostent\_r}.
-
-Per risolvere il problema dell'uso da parte delle due funzioni
-\func{gethostbyname} e \func{gethostbyaddr} di memoria statica che può essere
-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}), seguendo
-l'\href{http://www.ietf.org/rfc/rfc2553.txt}{RFC~2553} vennero introdotte due
-nuove funzioni di risoluzione,\footnote{le funzioni sono presenti nelle
-  \acr{glibc} versione 2.1.96, ma essendo considerate deprecate (vedi
+\funcd{gethostent}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{netdb.h}
+\fdecl{struct hostent *gethostent(void)}
+\fdesc{Ottiene la voce successiva nel database dei nomi a dominio.} 
+}
+
+{La funzione ritorna l'indirizzo ad una struttura \struct{hostent} in caso di
+  successo e \val{NULL} per un errore.}
+\end{funcproto}
+
+La funzione dovrebbe ritornare (come puntatore alla solita struttura
+\struct{hostent} allocata internamente) la voce successiva nel database dei
+nomi a dominio, ma questo ha un significato soltato quando è relativo alla
+lettura dei dati da un file come \conffile{/etc/hosts} e non per i risultati
+del DNS. Nel caso della \acr{glibc} questa viene usata allora solo per la
+lettura delle voci presenti in quest'ultimo, come avviene anche in altri
+sistemi unix-like, ed inoltre ignora le voci relative ad indirizzi IPv6.
+
+Della stessa funzione le \acr{glibc} forniscono anche una versione rientrante
+\funcd{gethostent\_r}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{netdb.h}
+\fdecl{struct hostent *gethostent\_r(struct hostent *ret, char *buf, size\_t buflen,\\
+\phantom{struct hostent *gethostent\_r(}struct hostent **result, int *h\_errnop);}
+\fdesc{Ottiene la voce successiva nel database dei nomi a dominio.} 
+}
+
+{La funzione ritorna $0$ in caso di successo e un valore non nullo per un errore.}
+\end{funcproto}
+
+La funzione ha lo stesso effetto di \func{gethostent}; gli argomenti servono a
+restituire i risultati in maniera rientrante e vanno usati secondo le modalità
+già illustrate per \func{gethostbyname\_r} e \func{gethostbyname2\_r}.
+
+Dati i limiti delle funzioni \func{gethostbyname} e \func{gethostbyaddr} con
+l'uso di memoria statica che può essere 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}),
+è stata successivamente proposta,
+nell'\href{http://www.ietf.org/rfc/rfc2553.txt}{RFC~2553} un diversa
+interfaccia con l'introduzione due nuove funzioni di
+risoluzione,\footnote{dette funzioni sono presenti nelle \acr{glibc} versione
+  2.1.96, ma essendo considerate deprecate (vedi
   sez.~\ref{sec:sock_advanced_name_services}) sono state rimosse nelle
   versioni successive.} \funcd{getipnodebyname} e \funcd{getipnodebyaddr}, i
 cui prototipi sono:
@@ -1086,7 +1118,6 @@ la necessità di disallocare 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{funcproto}{
 \fhead{netdb.h}
 \fhead{sys/types.h}
@@ -1107,10 +1138,10 @@ Infine per concludere la nostra panoramica sulle funzioni di risoluzione dei
 nomi dobbiamo citare le funzioni che permettono di interrogare gli altri
 servizi di risoluzione dei nomi illustrati in sez.~\ref{sec:sock_resolver}; in
 generale infatti ci sono una serie di funzioni nella forma
-\texttt{getXXXbyname} e \texttt{getXXXbyaddr} (dove \texttt{XXX} indica il
-servizio) per ciascuna delle informazioni di rete mantenute dal \textit{Name
-  Service Switch} che permettono rispettivamente di trovare una corrispondenza
-cercando per nome o per numero.
+\texttt{get\textsl{XXX}byname} e \texttt{get\textsl{XXX}byaddr} (dove
+\texttt{\textsl{XXX}} indica il servizio) per ciascuna delle informazioni di
+rete mantenute dal \textit{Name Service Switch} che permettono rispettivamente
+di trovare una corrispondenza cercando per nome o per numero.
 
 L'elenco di queste funzioni è riportato nelle colonne finali di
 tab.~\ref{tab:name_resolution_functions}, dove le si sono suddivise rispetto
@@ -1159,27 +1190,30 @@ ecc.) da associare alle rispettive porte. Le due funzioni da utilizzare per
 questo sono \funcd{getservbyname} e \funcd{getservbyport}, 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)} 
-
-  Risolvono il nome di un servizio nel rispettivo numero di porta e viceversa.
-       
-  \bodydesc{Ritornano il puntatore ad una struttura \struct{servent} con i
-    risultati in caso di successo, o \val{NULL} in caso di errore.}
-\end{functions}
+
+
+
+\begin{funcproto}{
+\fhead{netdb.h} 
+\fdecl{struct servent *getservbyname(const char *name, const char *proto)}
+\fdecl{struct servent *getservbyport(int port, const char *proto)} 
+\fdesc{Risolvono il nome di un servizio nel rispettivo numero di porta e viceversa.} 
+}
+
+{Le funzioni ritornano il puntatore ad una struttura \struct{servent} con i
+    risultati in caso di successo e \val{NULL} per un errore.}
+\end{funcproto}
 
 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 \conffile{/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 \conffile{/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
+che indica il protocollo per il quale si intende effettuare la ricerca (le
+informazioni mantenute in \conffile{/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 di 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
+  \conffile{/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},
@@ -1226,22 +1260,21 @@ 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 \conffile{/etc/services} e si posiziona al suo inizio.
-
-  \funcdecl{struct servent *getservent(void)}
-  Legge la voce successiva nel file \conffile{/etc/services}.      
 
-  \funcdecl{void endservent(void)} 
-  Chiude il file \conffile{/etc/services}.
+\begin{funcproto}{
+\fhead{netdb.h} 
+\fdecl{struct servent *getservent(void)}
+\fdesc{Legge la voce successiva nel file \conffile{/etc/services}.} 
+\fdecl{void setservent(int stayopen)} 
+\fdesc{Apre il file \conffile{/etc/services} e si posiziona al suo inizio.} 
+\fdecl{void endservent(void)}
+\fdesc{Chiude il file \conffile{/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 \val{NULL} in caso di
-    errore o fine del file.}
-\end{functions}
+{Le due funzioni \func{setservent} e \func{endservent} non ritornano nulla,
+  \func{getservent} restituisce il puntatore ad una struttura \struct{servent}
+  in caso di successo e \val{NULL} per un errore o fine del file.}
+\end{funcproto}
 
 La prima funzione, \func{getservent}, legge una singola voce a partire dalla
 posizione corrente in \conffile{/etc/services}, pertanto si può eseguire una
@@ -1250,22 +1283,7 @@ aperto provvede automaticamente ad aprirlo, nel qual caso leggerà la prima
 voce. La seconda funzione, \func{setservent}, permette di aprire il file
 \conffile{/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{getservbyport}.\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, \func{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.
+modo si può far ricominciare da capo una lettura sequenziale. 
 
 \begin{table}[!htb]
   \centering
@@ -1286,6 +1304,23 @@ rimandando alle rispettive pagine di manuale.
   \label{tab:name_sequential_read}
 \end{table}
 
+L'argomento \param{stayopen} di \func{setservent}, se diverso da zero, fa sì
+che il file resti aperto anche fra diverse chiamate a \func{getservbyname} e
+\func{getservbyport}; 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, \func{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.
+
 
 \subsection{Le funzioni avanzate per la risoluzione dei nomi}
 \label{sec:sock_advanced_name_services}
@@ -1295,10 +1330,10 @@ risoluzione di nomi ed indirizzi IP, ma abbiamo già visto come esse soffrano
 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
-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.
+alcuni di questi inconvenienti, comunque esse non forniscono una interfaccia
+sufficientemente generica.\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.}
 
 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
@@ -1308,26 +1343,27 @@ 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},\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
+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
-di un servizio; il suo prototipo è:
-\begin{functions}
-  \headdecl{netdb.h} 
-  \headdecl{sys/socket.h} 
-  \headdecl{netdb.h} 
+di un servizio; la funzione è stata introdotta, insieme a \func{getnameinfo}
+che vedremo più avanti,
+nell'\href{http://www.ietf.org/rfc/rfc2553.txt}{RFC~2553} ed il suo prototipo è:
 
-  \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.
+\begin{funcproto}{
+\fhead{netdb.h}
+\fhead{sys/socket.h} 
+\fdecl{int getaddrinfo(const char *node, const char *service, const
+    struct addrinfo *hints, \\
+\phantom{int getaddrinfo(}struct addrinfo **res)}
+\fdesc{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}
+{La funzione ritorna $0$ in caso di successo e un codice di errore diverso da
+  zero per un errore.}
+\end{funcproto}
 
 La funzione prende come primo argomento il nome della macchina che si vuole
 risolvere, specificato tramite la stringa \param{node}. Questo argomento,
@@ -1358,7 +1394,7 @@ puntatore iniziale ad una \textit{linked list} di strutture di tipo
 
 \begin{figure}[!htb]
   \footnotesize \centering
-  \begin{minipage}[c]{0.80\textwidth}
+  \begin{minipage}[c]{0.90\textwidth}
     \includestruct{listati/addrinfo.h}
   \end{minipage}
   \caption{La struttura \structd{addrinfo} usata nella nuova interfaccia POSIX
@@ -1370,7 +1406,7 @@ Come illustrato la struttura \struct{addrinfo}, la cui definizione è 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. La definizione è ripresa direttamente dal file \headfiled{netdb.h}
-in questa struttura viene dichiarata, la pagina di manuale riporta
+in cui 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.
@@ -1384,14 +1420,14 @@ 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.
+Tutti i campi seguenti vengono usati soltanto in uscita e devono essere nulli
+o \val{NULL} in ingresso; 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
 \val{NULL} come valore per l'argomento \param{hints} si possono compiere
@@ -1403,9 +1439,9 @@ quale siano stati opportunamente impostati i valori dei campi
 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
+sono presi in considerazione solo \const{AF\_INET} e \const{AF\_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
+valore \const{AF\_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,
@@ -1422,22 +1458,15 @@ nella selezione.
 \begin{table}[!htb]
   \centering
   \footnotesize
-  \begin{tabular}[c]{|l|p{10cm}|}
+  \begin{tabular}[c]{|l|p{8cm}|}
     \hline
     \textbf{Costante} & \textbf{Significato} \\
     \hline
     \hline
-    \constd{AI\_PASSIVE}    & Viene utilizzato per ottenere un indirizzo in
-                              formato adatto per una successiva chiamata a
-                              \func{bind}. Se specificato quando si è usato 
-                              \val{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 verranno restituiti in formato adatto ad
-                              una chiamata a \func{connect} o \func{sendto}.\\
+    \const{AI\_ADDRCONFIG} & 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}.\\ 
     \constd{AI\_CANONNAME}  & Richiede la restituzione del nome canonico della
                               macchina, che verrà salvato in una stringa il cui
                               indirizzo sarà restituito nel campo
@@ -1452,12 +1481,35 @@ nella selezione.
                               tab.~\ref{tab:addrinfo_error_code}), in questo
                               modo si evita ogni chiamata alle funzioni di
                               risoluzione.\\ 
+    \constd{AI\_NUMERICSERVICE}& Analogo di \const{AI\_NUMERICHOST} per la
+                                 risoluzione di un servizio, con 
+                                 \param{service} che deve essere espresso in forma
+                                 numerica.\\ 
+    \constd{AI\_PASSIVE}    & Viene utilizzato per ottenere un indirizzo in
+                              formato adatto per una successiva chiamata a
+                              \func{bind}. Se specificato quando si è usato 
+                              \val{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 verranno restituiti in formato adatto ad
+                              una chiamata a \func{connect} o \func{sendto}.\\
     \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}.\\ 
+                             tab.~\ref{tab:sock_getipnodebyname_flags}.\\  
+    \hline
+    \const{AI\_CANONIDN}   & Se il nome canonico richiesto con
+                             \const{AI\_CANONNAME} è codificato con questo
+                             flag la codifica viene convertita in forma
+                             leggibile nella localizzazione corrente.\\ 
+    \const{AI\_IDN}        & Se specificato il nome viene convertito, se
+                             necessario, nella codifica IDN, usando la
+                             localizzazione corrente.\\ 
+    \const{AI\_IDN\_ALLOW\_UNASSIGNED} & attiva il controllo 
+                                         \texttt{IDNA\_ALLOW\_UNASSIGNED}.\\ 
+    \const{AI\_AI\_IDN\_USE\_STD3\_ASCII\_RULES} & attiva il controllo
+                                            \texttt{IDNA\_USE\_STD3\_ASCII\_RULES}\\ 
     \hline
   \end{tabular}
   \caption{Costanti associate ai bit del campo \var{ai\_flags} della struttura 
@@ -1465,14 +1517,30 @@ nella selezione.
   \label{tab:ai_flags_values}
 \end{table}
 
-
-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.
+% TODO mettere riferimento a IDNA_ALLOW_UNASSIGNED e IDNA_USE_STD3_ASCII_RULES
+
+Infine gli ultimi dettagli si controllano con il 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. 
+
+Nella seconda parte della tabella si sono riportati i valori delle costanti
+aggiunte a partire dalle \acr{glibc} 2.3.4 per gestire la
+internazionalizazione dei nomi a dominio (IDN o \textit{Internationalized
+  Domain Names}) secondo quanto specificato
+nell'\href{http://www.ietf.org/rfc/rfc3490.txt}{RFC~3490} (potendo cioè usare
+codifiche di caratteri che consentono l'espressione di nomi a dominio in
+qualunque lingua).
+
+Come accennato passando un valore \val{NULL} per l'argomento \param{hints} si
+effettua una risuluzione generica, equivalente ad aver impostato un valore
+nullo per \var{ai\_family} e \var{ai\_socktype}, un valore \const{AF\_UNSPEC}
+per \var{ai\_family} e il valore \code{(AI\_V4MAPPED|AI\_ADDRCONFIG)} per
+\var{ai\_flags}. 
 
 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
@@ -1490,11 +1558,21 @@ corrispondente è riportato tramite \var{errno}.
     \textbf{Costante} & \textbf{Significato} \\
     \hline
     \hline
+    \constd{EAI\_ADDRFAMILY}& La richiesta non ha nessun indirizzo di rete
+                              per la famiglia di indirizzi specificata. \\
+    \constd{EAI\_AGAIN}   & Il DNS ha restituito un errore di risoluzione  
+                            temporaneo, si può ritentare in seguito. \\
+    \constd{EAI\_BADFLAGS}& Il campo \var{ai\_flags} contiene dei valori non
+                            validi per i flag o si è richiesto
+                            \const{AI\_CANONNAME} con \param{name} nullo. \\
+    \constd{EAI\_FAIL}    & Il DNS ha restituito un errore di risoluzione  
+                            permanente. \\
     \constd{EAI\_FAMILY}  & La famiglia di indirizzi richiesta non è
                             supportata. \\ 
-    \constd{EAI\_SOCKTYPE}& Il tipo di socket richiesto non è supportato. \\
-    \constd{EAI\_BADFLAGS}& Il campo \var{ai\_flags} contiene dei valori non
-                            validi. \\
+    \constd{EAI\_MEMORY}  & È stato impossibile allocare la memoria necessaria
+                            alle operazioni. \\
+    \constd{EAI\_NODATA}  & La macchina specificata esiste, ma non ha nessun
+                            indirizzo di rete definito. \\
     \constd{EAI\_NONAME}  & Il nome a dominio o il servizio non sono noti,
                             viene usato questo errore anche quando si specifica
                             il valore \val{NULL} per entrambi gli argomenti
@@ -1502,16 +1580,7 @@ corrispondente è riportato tramite \var{errno}.
     \constd{EAI\_SERVICE} & Il servizio richiesto non è disponibile per il tipo
                             di socket richiesto, anche se può esistere per
                             altri tipi di socket. \\
-    \constd{EAI\_ADDRFAMILY}& La rete richiesta non ha nessun indirizzo di rete
-                              per la famiglia di indirizzi specificata. \\
-    \constd{EAI\_NODATA}  & La macchina specificata esiste, ma non ha nessun
-                            indirizzo di rete definito. \\
-    \constd{EAI\_MEMORY}  & È stato impossibile allocare la memoria necessaria
-                            alle operazioni. \\
-    \constd{EAI\_FAIL}    & Il DNS ha restituito un errore di risoluzione  
-                            permanente. \\
-    \constd{EAI\_AGAIN}   & Il DNS ha restituito un errore di risoluzione  
-                            temporaneo, si può ritentare in seguito. \\
+    \constd{EAI\_SOCKTYPE}& Il tipo di socket richiesto non è supportato. \\
     \constd{EAI\_SYSTEM}  & C'è stato un errore di sistema, si può controllare
                             \var{errno} per i dettagli. \\
 %    \hline
@@ -1529,35 +1598,36 @@ corrispondente è riportato tramite \var{errno}.
 \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 è \funcd{gai\_strerror} ed il suo prototipo è:
-\begin{functions}
-  \headdecl{netdb.h} 
-
-  \funcdecl{const char *gai\_strerror(int errcode)}
+fornita una apposita funzione, simile a \func{strerror}, che consente di
+utilizzare direttamente il codice restituito dalla funzione per stampare a
+video un messaggio esplicativo; la funzione è \funcd{gai\_strerror} ed il suo
+prototipo è:
 
-  Fornisce il messaggio corrispondente ad un errore di \func{getaddrinfo}.
+\begin{funcproto}{
+\fhead{netdb.h} 
+\fdecl{const char *gai\_strerror(int errcode)}
+\fdesc{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 ritorna il puntatore alla stringa contenente il messaggio di
+  errore.}
+\end{funcproto}
 
 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.
+costante ed accessibile in sola lettura, la funzione è rientrante.
 
 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}.
+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
@@ -1575,7 +1645,7 @@ 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}[!htbp]
+\begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{\codesamplewidth}
     \includecodesample{listati/mygetaddr.c}
@@ -1604,8 +1674,8 @@ 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.}
+errore ed uscire (questa eventualità non dovrebbe comunque 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
@@ -1628,7 +1698,7 @@ puntatore al campo contenente l'indirizzo IP nella struttura puntata dal campo
   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{\&}).}
+  in 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
@@ -1644,8 +1714,8 @@ 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
+\begin{Console}
+[piccardi@gont sources]$ \textbf{./mygetaddr -c  gapil.truelite.it echo}
 Canonical name sources2.truelite.it
 IPv4 address:
         Indirizzo 62.48.34.25
@@ -1655,28 +1725,30 @@ IPv4 address:
         Indirizzo 62.48.34.25
         Protocollo 17
         Porta 7
-\end{Verbatim}
+\end{Console}
 %$
 
 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}.
+\begin{funcproto}{
+\fhead{netdb.h}
+\fdecl{void freeaddrinfo(struct addrinfo *res)}
+\fdesc{Libera la memoria allocata da una precedente chiamata a \func{getaddrinfo}.} 
+}
 
-  \bodydesc{La funzione non restituisce nessun codice di errore.}
-\end{functions}
+{La funzione non restituisce nessun codice di errore.}
+\end{funcproto}
 
 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}.
+per \param{res} ed usare un indirizzo non valido o già liberato può avere
+conseguenze non prevedibili.
 
 Si tenga presente infine che se si copiano i risultati da una delle strutture
 \struct{addrinfo} restituite nella lista indicizzata da \param{res}, occorre
@@ -1690,19 +1762,20 @@ 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{getipnodebyname} e \func{getservbyname} è
 \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.
+\begin{funcproto}{
+\fhead{netdb.h}
+\fhead{sys/socket.h}
+\fdecl{int getnameinfo(const struct sockaddr *sa, socklen\_t salen, \\
+\phantom{int getnameinfo(}char *host, size\_t hostlen, char *serv, size\_t
+servlen, int flags)} 
+\fdesc{Effettua una risoluzione di un indirizzo di rete 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 funzione ritorna $0$ in caso di successo e un codice di errore diverso da
+  zero per un errore.}
+\end{funcproto}
 
 La principale caratteristica di \func{getnameinfo} è che la funzione è in
 grado di eseguire una risoluzione inversa in maniera indipendente dal
@@ -1714,36 +1787,47 @@ IPv6, la cui dimensione deve comunque essere specificata con l'argomento
 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 \val{NULL} come argomento,
-così che la corrispondente informazione non verrà richiesta. Infine l'ultimo
+due argomenti \param{hostlen} e \param{servlen}. Quando non si è
+interessati ad uno dei due, si può passare il valore \val{NULL} come argomento,
+così che la corrispondente informazione non venga 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}.
+tab.~\ref{tab:getnameinfo_flags}, nella seconda parte della tabella si sono
+aggiunti i valori introdotto con le \acr{glibc} 2.3.4 per gestire la
+internazionalizzione dei nomi a dominio.
 
 \begin{table}[!htb]
   \centering
   \footnotesize
-  \begin{tabular}[c]{|l|p{10cm}|}
+  \begin{tabular}[c]{|l|p{8cm}|}
     \hline
     \textbf{Costante} & \textbf{Significato} \\
     \hline
     \hline
+    \constd{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.\\
     \constd{NI\_NOFQDN}     & Richiede che venga restituita solo il nome della
                               macchina all'interno del dominio al posto del
                               nome completo (FQDN).\\
+    \constd{NI\_NAMEREQD}   & Richiede la restituzione di un errore se il nome
+                              non può essere risolto.\\
     \constd{NI\_NUMERICHOST}& Richiede che venga restituita la forma numerica
                               dell'indirizzo (questo succede sempre se il nome
                               non può essere ottenuto).\\ 
-    \constd{NI\_NAMEREQD}   & Richiede la restituzione di un errore se il nome
-                              non può essere risolto.\\
     \constd{NI\_NUMERICSERV}& Richiede che il servizio venga restituito in
-                              forma numerica (attraverso il numero di porta).\\
-    \constd{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.\\
+                              forma numerica (attraverso il numero di
+                              porta).\\
+    \hline
+    \const{NI\_IDN}        & Se specificato il nome restituito viene convertito usando la
+                             localizzazione corrente, se necessario, nella
+                             codifica IDN.\\ 
+    \const{NI\_IDN\_ALLOW\_UNASSIGNED} & attiva il controllo 
+                                       \texttt{IDNA\_ALLOW\_UNASSIGNED}.\\ 
+    \const{NI\_AI\_IDN\_USE\_STD3\_ASCII\_RULES} & attiva il controllo
+                                       \texttt{IDNA\_USE\_STD3\_ASCII\_RULES}\\ 
     \hline
   \end{tabular}
   \caption{Costanti associate ai bit dell'argomento \param{flags} della  
@@ -1779,7 +1863,7 @@ fig.~\ref{fig:sockconn_code}, il codice completo è nel file \file{SockUtil.c}
 dei sorgenti allegati alla guida, che contiene varie funzioni di utilità per
 l'uso dei socket.
 
-\begin{figure}[!htbp]
+\begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{\codesamplewidth}
     \includecodesample{listati/sockconn.c}
@@ -1795,38 +1879,42 @@ cui sarà effettuata la risoluzione; seguono il protocollo da usare (da
 specificare con il valore numerico di \conffile{/etc/protocols}) ed il tipo di
 socket (al solito specificato con i valori illustrati in
 sez.~\ref{sec:sock_type}).  La funzione ritorna il valore del file descriptor
-associato al socket (un numero positivo) in caso di successo, o -1 in caso di
-errore; per risolvere il problema di non poter passare indietro i valori di
-ritorno di \func{getaddrinfo} contenenti i relativi codici di
-errore\footnote{non si può avere nessuna certezza che detti valori siano
-  negativi, è questo è invece necessario per evitare ogni possibile ambiguità
-  nei confronti del valore di ritorno in caso di successo.} si sono stampati i
-messaggi d'errore direttamente nella funzione.
-
-Una volta definite le variabili necessarie (\texttt{\small 3--5}) la funzione
+associato al socket (un numero positivo) in caso di successo, o $-1$ in caso
+di errore.
+
+Per risolvere il problema di non poter passare indietro i valori di ritorno di
+\func{getaddrinfo} contenenti i relativi codici di errore si sono stampati i
+messaggi d'errore direttamente nella funzione; infatti non si può avere
+nessuna certezza che detti valori siano negativi e per cui stampare subito
+l'errore diventa necessario per evitare ogni possibile ambiguità nei confronti
+del valore di ritorno in caso di successo.
+
+Una volta definite le variabili occorrenti (\texttt{\small 3--5}) la funzione
 prima (\texttt{\small 6}) azzera il contenuto della struttura \var{hint} e poi
 provvede (\texttt{\small 7--9}) ad inizializzarne i valori necessari per la
 chiamata (\texttt{\small 10}) a \func{getaddrinfo}. Di quest'ultima si
-controlla (\texttt{\small 12--16}) il codice di ritorno, in modo da stampare un
-avviso di errore, azzerare \var{errno} ed uscire in caso di errore.  Dato che
-ad una macchina possono corrispondere più indirizzi IP, e di tipo diverso (sia
-IPv4 che IPv6), mentre il servizio può essere in ascolto soltanto su uno solo
-di questi, si provvede a tentare la connessione per ciascun indirizzo
-restituito all'interno di un ciclo (\texttt{\small 18--40}) di scansione della
-lista restituita da \func{getaddrinfo}, ma prima (\texttt{\small 17}) si salva
-il valore del puntatore per poterlo riutilizzare alla fine per disallocare la
-lista.
+controlla (\texttt{\small 12--16}) il codice di ritorno, in modo da stampare
+un avviso di errore, azzerare \var{errno} ed uscire in caso di errore.  
+
+Dato che ad una macchina possono corrispondere più indirizzi IP, e di tipo
+diverso (sia IPv4 che IPv6), mentre il servizio può essere in ascolto soltanto
+su uno solo di questi, si provvede a tentare la connessione per ciascun
+indirizzo restituito all'interno di un ciclo (\texttt{\small 18--40}) di
+scansione della lista restituita da \func{getaddrinfo}, ma prima
+(\texttt{\small 17}) si salva il valore del puntatore per poterlo riutilizzare
+alla fine per disallocare la lista.
 
 Il ciclo viene ripetuto (\texttt{\small 18}) fintanto che si hanno indirizzi
 validi, ed inizia (\texttt{\small 19}) con l'apertura del socket; se questa
 fallisce si controlla (\texttt{\small 20}) se sono disponibili altri
 indirizzi, nel qual caso si passa al successivo (\texttt{\small 21}) e si
 riprende (\texttt{\small 22}) il ciclo da capo; se non ve ne sono si stampa
-l'errore ritornando immediatamente (\texttt{\small 24--27}). Quando la
-creazione del socket ha avuto successo si procede (\texttt{\small 29})
-direttamente con la connessione, di nuovo in caso di fallimento viene ripetuto
-(\texttt{\small 30--38}) il controllo se vi sono o no altri indirizzi da
-provare nella stessa modalità fatta in precedenza, aggiungendovi però in
+l'errore ritornando immediatamente (\texttt{\small 24--27}). 
+
+Quando la creazione del socket ha avuto successo si procede (\texttt{\small
+  29}) direttamente con la connessione, di nuovo in caso di fallimento viene
+ripetuto (\texttt{\small 30--38}) il controllo se vi sono o no altri indirizzi
+da provare nella stessa modalità fatta in precedenza, aggiungendovi però in
 entrambi i casi (\texttt{\small 32} e (\texttt{\small 36}) la chiusura del
 socket precedentemente aperto, che non è più utilizzabile.
 
@@ -1840,16 +1928,6 @@ ritornata contiene indirizzi IPv6 o IPv4, in quanto si fa uso direttamente dei
 dati relativi alle strutture degli indirizzi di \struct{addrinfo} che sono
 opachi rispetto all'uso della funzione \func{connect}.
 
-\begin{figure}[!htbp]
-  \footnotesize \centering
-  \begin{minipage}[c]{\codesamplewidth}
-    \includecodesample{listati/TCP_echo_fifth.c}
-  \end{minipage}
-  \normalsize
-  \caption{Il nuovo codice per la connessione del client \textit{echo}.}
-  \label{fig:TCP_echo_fifth}
-\end{figure}
-
 Per usare questa funzione possiamo allora modificare ulteriormente il nostro
 programma client per il servizio \textit{echo}; in questo caso rispetto al
 codice usato finora per collegarsi (vedi fig.~\ref{fig:TCP_echo_client_1})
@@ -1861,7 +1939,25 @@ codice completo è nel file \file{TCP\_echo\_fifth.c} dei sorgenti allegati)
 consente di utilizzare come argomento del programma un nome a dominio al posto
 dell'indirizzo numerico, e può utilizzare sia indirizzi IPv4 che IPv6.
 
-\begin{figure}[!htbp]
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{\codesamplewidth}
+    \includecodesample{listati/TCP_echo_fifth.c}
+  \end{minipage}
+  \normalsize
+  \caption{Il nuovo codice per la connessione del client \textit{echo}.}
+  \label{fig:TCP_echo_fifth}
+\end{figure}
+
+La seconda funzione di ausilio che abbiamo creato è \texttt{sockbind}, il cui
+corpo principale è riportato in fig.~\ref{fig:sockbind_code} (al solito il
+sorgente completo è nel file \file{sockbind.c} dei sorgenti allegati alla
+guida). Come si può notare la funzione è del tutto analoga alla precedente
+\texttt{sockconn}, e prende gli stessi argomenti, però invece di eseguire una
+connessione con \func{connect} si limita a chiamare \func{bind} per collegare
+il socket ad una porta.
+
+\begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{\codesamplewidth}
     \includecodesample{listati/sockbind.c}
@@ -1871,14 +1967,6 @@ dell'indirizzo numerico, e può utilizzare sia indirizzi IPv4 che IPv6.
   \label{fig:sockbind_code}
 \end{figure}
 
-La seconda funzione di ausilio è \texttt{sockbind}, il cui corpo principale è
-riportato in fig.~\ref{fig:sockbind_code} (al solito il sorgente completo è
-nel file \file{sockbind.c} dei sorgenti allegati alla guida). Come si può
-notare la funzione è del tutto analoga alla precedente \texttt{sockconn}, e
-prende gli stessi argomenti, però invece di eseguire una connessione con
-\func{connect} si limita a chiamare \func{bind} per collegare il socket ad una
-porta.
-
 Dato che la funzione è pensata per essere utilizzata da un server ci si può
 chiedere a quale scopo mantenere l'argomento \param{host} quando l'indirizzo
 di questo è usualmente noto. Si ricordi però quanto detto in
@@ -1903,11 +1991,11 @@ identici, solo che si è sostituita (\texttt{\small 31}) la chiamata a
 (\texttt{\small 43--44}) della funzione è identica.
 
 Si noti come anche in questo caso si siano inserite le stampe degli errori
-sullo standard error, nonostante la funzione possa essere invocata da un
-demone. Nel nostro caso questo non è un problema in quanto se la funzione non
-ha successo il programma deve uscire immediatamente prima di essere posto in
-background, e può quindi scrivere gli errori direttamente sullo standard
-error.
+sullo \textit{standard error}, nonostante la funzione possa essere invocata da
+un demone. Nel nostro caso questo non è un problema in quanto se la funzione
+non ha successo il programma deve uscire immediatamente prima di essere posto
+in background, e può quindi scrivere gli errori direttamente sullo
+\textit{standard error}.
 
 \begin{figure}[!htbp]
   \footnotesize \centering
@@ -1928,21 +2016,24 @@ che si cura anche della eventuale risoluzione di un indirizzo specifico sul
 quale si voglia far ascoltare il server.
 
 
-
 \section{Le opzioni dei socket}
 \label{sec:sock_options}
 
 Benché dal punto di vista del loro uso come canali di trasmissione di dati i
-socket siano trattati allo stesso modo dei file, ed acceduti tramite i file
-descriptor, la normale interfaccia usata per la gestione dei file non è
-sufficiente a poterne controllare tutte le caratteristiche, che variano tra
-l'altro a seconda del loro tipo (e della relativa forma di comunicazione
-sottostante). In questa sezione vedremo allora quali sono le funzioni dedicate
-alla gestione delle caratteristiche specifiche dei vari tipi di socket, le
-cosiddette \textit{socket options}.
+socket vengano trattati allo stesso modo dei file, siano acceduti tramite i
+file descriptor, e gestiti con le ordinarie funzioni di lettura e scrittura
+dei file, l'interfaccia standard usata per la gestione dei file generici non è
+comunque sufficiente a poterne controllare tutte le caratteristiche
+specifiche, considerato poi che queste variano a seconda del tipo di socket (e
+della relativa forma di comunicazione sottostante). 
+
+In questa sezione vedremo allora quali sono le funzioni dedicate alla gestione
+delle caratteristiche specifiche dei vari tipi di socket, le cosiddette
+\textit{socket options}, ma soprattutto analizzaremo quali sono queste opzioni
+e quali caretteristiche e comportamenti dei socket permettono di controllare.
 
 
-\subsection{Le funzioni \func{setsockopt} e \func{getsockopt}}
+\subsection{Le funzioni di gestione delle opzioni dei socket}
 \label{sec:sock_setsockopt}
 
 Le varie caratteristiche dei socket possono essere gestite attraverso l'uso di
@@ -1950,16 +2041,17 @@ due funzioni generiche che permettono rispettivamente di impostarle e di
 recuperarne il valore corrente. La prima di queste due funzioni, quella usata
 per impostare le \textit{socket options}, è \funcd{setsockopt}, ed il suo
 prototipo è:
-\begin{functions}
-  \headdecl{sys/socket.h}
-  \headdecl{sys/types.h}
 
-  \funcdecl{int setsockopt(int sock, int level, int optname, const void
+\begin{funcproto}{
+\fhead{sys/socket.h}
+\fhead{sys/types.h}
+\fdecl{int setsockopt(int sock, int level, int optname, const void
     *optval, socklen\_t optlen)}
-  Imposta le opzioni di un socket.
+\fdesc{Imposta le opzioni di un socket.} 
+}
 
-  \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
-    errore, nel qual caso \var{errno} assumerà i valori:
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+  caso \var{errno} assumerà uno dei valori: 
   \begin{errlist}
   \item[\errcode{EBADF}]  il file descriptor \param{sock} non è valido.
   \item[\errcode{EFAULT}] l'indirizzo \param{optval} non è valido.
@@ -1970,8 +2062,7 @@ prototipo è:
     un socket.
   \end{errlist}
 }
-\end{functions}
-
+\end{funcproto}
 
 Il primo argomento della funzione, \param{sock}, indica il socket su cui si
 intende operare; per indicare l'opzione da impostare si devono usare i due
index 2d31d6c73b17d2dc57d880df48a8e7a83fed49b1..ceb724ccd7387cffe6aae610a04f8dfd40008ffb 100644 (file)
@@ -199,36 +199,36 @@ comunicazione.
        \textbf{Nome}&\textbf{Valore}&\textbf{Utilizzo}&\textbf{Man page} \\
        \hline
        \hline
-       \constd{PF\_UNSPEC}   & 0& Non specificato               &            \\
-       \constd{PF\_LOCAL}    & 1& Local communication           & unix(7)    \\
-       \constd{PF\_UNIX}, \constd{PF\_FILE}&1&Sinonimi di \const{PF\_LOCAL}& \\
-       \constd{PF\_INET}     & 2& IPv4 Internet protocols       & ip(7)      \\
-       \constd{PF\_AX25}     & 3& Amateur radio AX.25 protocol  &            \\
-       \constd{PF\_IPX}      & 4& IPX - Novell protocols        &            \\
-       \constd{PF\_APPLETALK}& 5& Appletalk                     & ddp(7)     \\
-       \constd{PF\_NETROM}   & 6& Amateur radio NetROM          &            \\
-       \constd{PF\_BRIDGE}   & 7& Multiprotocol bridge          &            \\
-       \constd{PF\_ATMPVC}   & 8& Access to raw ATM PVCs        &            \\
-       \constd{PF\_X25}      & 9& ITU-T X.25 / ISO-8208 protocol& x25(7)     \\
-       \constd{PF\_INET6}    &10& IPv6 Internet protocols       & ipv6(7)    \\
-       \constd{PF\_ROSE}     &11& Amateur Radio X.25 PLP        &            \\
-       \constd{PF\_DECnet}   &12& Reserved for DECnet project   &            \\
-       \constd{PF\_NETBEUI}  &13& Reserved for 802.2LLC project &            \\
-       \constd{PF\_SECURITY} &14& Security callback pseudo AF   &            \\
-       \constd{PF\_KEY}      &15& PF\_KEY key management API    &            \\
-       \constd{PF\_NETLINK}  &16& Kernel user interface device  & netlink(7) \\
-       \constd{PF\_ROUTE}    &16& Sinonimo di \const{PF\_NETLINK} emula BSD.&\\
-       \constd{PF\_PACKET}   &17& Low level packet interface    & packet(7)  \\
-       \constd{PF\_ASH}      &18& Ash                           &    \\
-       \constd{PF\_ECONET}   &19& Acorn Econet                  &    \\
-       \constd{PF\_ATMSVC}   &20& ATM SVCs                      &    \\
-       \constd{PF\_SNA}      &22& Linux SNA Project             &    \\
-       \constd{PF\_IRDA}     &23& IRDA socket (infrarossi)      &    \\
-       \constd{PF\_PPPOX}    &24& PPPoX socket                  &    \\
-       \constd{PF\_WANPIPE}  &25& Wanpipe API socket            &    \\
-       \constd{PF\_LLC}      &26& Linux LLC                     &    \\
-       \constd{PF\_CAN}      &29& Controller Are Network        &    \\
-       \constd{PF\_BLUETOOTH}&31& Bluetooth socket              &    \\
+       \constd{AF\_UNSPEC}   & 0& Non specificato               &            \\
+       \constd{AF\_LOCAL}    & 1& Local communication           & unix(7)    \\
+       \constd{AF\_UNIX}, \constd{AF\_FILE}&1&Sinonimi di \const{AF\_LOCAL}& \\
+       \constd{AF\_INET}     & 2& IPv4 Internet protocols       & ip(7)      \\
+       \constd{AF\_AX25}     & 3& Amateur radio AX.25 protocol  &            \\
+       \constd{AF\_IPX}      & 4& IPX - Novell protocols        &            \\
+       \constd{AF\_APPLETALK}& 5& Appletalk                     & ddp(7)     \\
+       \constd{AF\_NETROM}   & 6& Amateur radio NetROM          &            \\
+       \constd{AF\_BRIDGE}   & 7& Multiprotocol bridge          &            \\
+       \constd{AF\_ATMPVC}   & 8& Access to raw ATM PVCs        &            \\
+       \constd{AF\_X25}      & 9& ITU-T X.25 / ISO-8208 protocol& x25(7)     \\
+       \constd{AF\_INET6}    &10& IPv6 Internet protocols       & ipv6(7)    \\
+       \constd{AF\_ROSE}     &11& Amateur Radio X.25 PLP        &            \\
+       \constd{AF\_DECnet}   &12& Reserved for DECnet project   &            \\
+       \constd{AF\_NETBEUI}  &13& Reserved for 802.2LLC project &            \\
+       \constd{AF\_SECURITY} &14& Security callback pseudo AF   &            \\
+       \constd{AF\_KEY}      &15& AF\_KEY key management API    &            \\
+       \constd{AF\_NETLINK}  &16& Kernel user interface device  & netlink(7) \\
+       \constd{AF\_ROUTE}    &16& Sinonimo di \const{AF\_NETLINK} emula BSD.&\\
+       \constd{AF\_PACKET}   &17& Low level packet interface    & packet(7)  \\
+       \constd{AF\_ASH}      &18& Ash                           &    \\
+       \constd{AF\_ECONET}   &19& Acorn Econet                  &    \\
+       \constd{AF\_ATMSVC}   &20& ATM SVCs                      &    \\
+       \constd{AF\_SNA}      &22& Linux SNA Project             &    \\
+       \constd{AF\_IRDA}     &23& IRDA socket (infrarossi)      &    \\
+       \constd{AF\_PPPOX}    &24& PPPoX socket                  &    \\
+       \constd{AF\_WANPIPE}  &25& Wanpipe API socket            &    \\
+       \constd{AF\_LLC}      &26& Linux LLC                     &    \\
+       \constd{AF\_CAN}      &29& Controller Are Network        &    \\
+       \constd{AF\_BLUETOOTH}&31& Bluetooth socket              &    \\
        \hline
   \end{tabular}
   \caption{Famiglie di protocolli definiti in Linux.} 
index c34d15dad4d51cd264d8fc0064271706c5357ecd..67a570d79377880c5a6b457a6d179b751f3f8588 100644 (file)
@@ -65,7 +65,7 @@ int main(int argc, char *argv[])
      * Init variables
      */
     memset(&hint, 0, sizeof(hint));
-    hint.ai_family = PF_UNSPEC;
+    hint.ai_family = AF_UNSPEC;
     /*
      * Input section: decode command line parameters 
      * Use getopt function
@@ -117,11 +117,11 @@ int main(int argc, char *argv[])
        case 'v':                                        /* set address type */
            j = strtol(optarg, NULL, 10);
            if (j == 4) {
-               hint.ai_family = PF_INET;
+               hint.ai_family = AF_INET;
                break;
            } 
            if (j == 6) {
-               hint.ai_family = PF_INET6;
+               hint.ai_family = AF_INET6;
                break;
            }
            printf("Wrong IP protocol version, use 4 o 6\n\n");
@@ -164,13 +164,13 @@ int main(int argc, char *argv[])
     ptr = res;                                        /* init list pointer */
     printf("Canonical name %s\n", ptr->ai_canonname); /* print cname */
     while (ptr != NULL) {                             /* loop on list */
-       if (ptr->ai_family == PF_INET) {              /* if IPv4 */
+       if (ptr->ai_family == AF_INET) {              /* if IPv4 */
            printf("IPv4 address: \n");
            addr = (struct sockaddr_in *) ptr->ai_addr;          /* address */
            port = ntohs(addr->sin_port);                        /* port */
            string = inet_ntop(addr->sin_family, &addr->sin_addr, 
                               buffer, sizeof(buffer));
-       } else if (ptr->ai_family == PF_INET6) {      /* if IPv6 */
+       } else if (ptr->ai_family == AF_INET6) {      /* if IPv6 */
            printf("IPv6 address: \n");
            addr6 = (struct sockaddr_in6 *) ptr->ai_addr;        /* address */
            port = ntohs(addr6->sin6_port);                      /* port */