Varie correzioni, completata revisione capitolo sull'I/O su file
[gapil.git] / sockctrl.tex
index 5103df1b9e57d9554c4a0ad2c57614d72630849e..9d5279e6ab62856b34ff617697608b440c23c03e 100644 (file)
@@ -1,6 +1,6 @@
 %% sockctrl.tex
 %%
-%% Copyright (C) 2004 Simone Piccardi.  Permission is granted to
+%% Copyright (C) 2004-2019 Simone Piccardi.  Permission is granted to
 %% copy, distribute and/or modify this document under the terms of the GNU Free
 %% Documentation License, Version 1.1 or any later version published by the
 %% Free Software Foundation; with the Invariant Sections being "Prefazione",
 %% license is included in the section entitled "GNU Free Documentation
 %% License".
 %%
+
 \chapter{La gestione dei socket}
 \label{cha:sock_generic_management}
 
-Esamineremo in questo capitolo una serie di funzionalità aggiuntive relative
+Esamineremo in questo capitolo una serie di funzionalità aggiuntive relative
 alla gestione dei socket, come la gestione della risoluzione di nomi e
-indirizzi, le impostazioni delle varie proprietà degli stessi, e le funzioni
-di controllo che vanno ad operare su di essi.
+indirizzi, le impostazioni delle varie proprietà ed opzioni relative ai
+socket, e le funzioni di controllo che permettono di modificarne il
+comportamento.
 
 
 \section{La risoluzione dei nomi}
 \label{sec:sock_name_resolution}
 
-Negli esempi precedenti abbiamo sempre identificato le singole macchine
-attraverso indirizzi numerici, sfruttando al più le funzioni di conversione
-elementari 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.
+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 \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}}
 \label{sec:sock_resolver}
 
-La risoluzione dei nomi è associata tradizionalmente al servizio del
-\textit{Domain Name Service} che permette di identificare le macchine su
-internet invece che per numero IP attraverso il relativo \textsl{nome a
-  dominio}. In realtà per DNS si intendono spesso i server che forniscono su
-internet questo servizio, mentre nel nostro caso affronteremo la problematica
-dal lato client, di un qualunque programma che necessita di compiere questa
-operazione.
+\itindbeg{resolver} La risoluzione dei nomi è associata tradizionalmente al
+servizio del \itindex{Domain~Name~Service~(DNS)} \textit{Domain Name Service}
+che permette di identificare le macchine su internet invece che per numero IP
+attraverso il relativo \textsl{nome a dominio}.\footnote{non staremo ad
+  entrare nei dettagli della definizione di cosa è un nome a dominio, dandolo
+  per noto, una introduzione alla problematica si trova in \cite{AGL} (cap.~9)
+  mentre per una trattazione approfondita di tutte le problematiche relative
+  al DNS si può fare riferimento a \cite{DNSbind}.} In realtà per DNS si
+intendono spesso i server che forniscono su internet questo servizio, mentre
+nel nostro caso affronteremo la problematica dal lato client, di un qualunque
+programma che necessita di compiere questa operazione.
 
-\begin{figure}[htb]
-  \centering
-  \includegraphics[width=10cm]{img/resolver}
-  \caption{Schema di funzionamento delle routine del \textit{resolver}.}
+\begin{figure}[!htb]
+  \centering \includegraphics[width=11cm]{img/resolver}
+  \caption{Schema di funzionamento delle funzioni del \textit{resolver}.}
   \label{fig:sock_resolver_schema}
 \end{figure}
 
-Inoltre quella fra nomi a dominio e indirizzi IP non è l'unica corrispondenza
+Inoltre quella fra nomi a dominio e indirizzi IP non è l'unica corrispondenza
 possibile fra nomi simbolici e valori numerici, come abbiamo visto anche in
 sez.~\ref{sec:sys_user_group} per le corrispondenze fra nomi di utenti e
-gruppi e relativi identificatori numerici; per quanto riguarda però tutti i
+gruppi e relativi identificatori numerici; per quanto riguarda però tutti i
 nomi associati a identificativi o servizi relativi alla rete il servizio di
-risoluzione è gestito in maniera unificata da un insieme di routine fornite
+risoluzione è gestito in maniera unificata da un insieme di funzioni fornite
 con le librerie del C, detto appunto \textit{resolver}.
 
-Lo schema di funzionamento del \textit{resolver} è illustrato in
+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
-sia fornito il supporto, come LDAP.
+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 mantenimento dei più vari tipi di informazioni su una
+  infrastruttura di questo tipo.}
 
-La configurazione del resolver attiene più alla amministrazione di sistema che
-alla programmazione, ciò non di meno, prima di trattare le varie funzioni che
-vale la pena farne una panoramica. Originariamente la configurazione
+La configurazione del \textit{resolver} attiene più alla amministrazione di
+sistema che alla programmazione, ciò non di meno, prima di trattare le varie
+funzioni di librerie utilizzate dai programmi, vale la pena fare una
+panoramica generale.  Originariamente la configurazione del \textit{resolver}
 riguardava esclusivamente le questioni relative alla gestione dei nomi a
 dominio, e prevedeva solo l'utilizzo del DNS e del file statico
-\file{/etc/hosts}, il file di configurazione principale è
-\file{/etc/resolv.conf} e contiene in sostanza l'elenco dei server DNS da
-contattare, a cui si affianca \file{/etc/host.conf} per indicare l'ordine in
-cui eseguire la risoluzione dei nomi (se usare prima i valori di
-\file{/etc/hosts} o il DNS); tralasciamo i dettagli che si trovano nelle
-relative pagine di manuale.
-
-Con il tempo però è divenuto possibile fornire diversi sostituti per
-l'utilizzo dei file statici, ed ai nomi a dominio si sono aggiunti altri nomi,
-come quelli associati alle reti ed ai gruppi di macchine definiti dal servizio
-NIS, o quelli dei protocolli e dei servizi mantenuti nei file statici
-\file{/etc/protocols} e \file{/etc/services}, tutte informazioni che
-normalmente non si trovano su un DNS, ma possono essere accedute in maniera
-centralizzata su opportuni server (ad esempio su LDAP) in grado di mantenerle.
-
-Questo ha portato alla creazione di un sistema di risoluzione più ampio, il
-\textit{Name Service Switch} di cui il \textit{resolver} viene a costituire un
-sottoinsieme. Questo sistema, che si applica anche alla risoluzioni fra nomi
-di utenti e gruppi e relativi identificatori, permette di definire in maniera
-generica (attraverso una serie di librerie dinamiche) sia i supporti su cui
-mantenere i dati di corrispondenza fra nomi e valori numerici, sia l'ordine in
-cui effettuare le ricerche sui vari supporti disponibili, ed è controllato dal
-file \file{/etc/nsswitch.conf}. Anche per questo si può fare riferimento alle
-pagine di manuale ed al relativo capitolo nel manuale \cite{glibc} delle
-\textsl{glibc}.
-
-In ogni caso, qualunque sia la modalità con cui ricevono i dati o il supporto
-su cui vengono mantenuti, dal punto di vista di un programma che deve
-effettuare la risoluzione di un nome, tutto quello che conta sono le funzioni
-che il \textit{resolver} mette a disposizione, e sono queste quelle che
-tratteremo nelle sezioni successive.
-
-
-
-\subsection{La risoluzione dei nomi a dominio}
-\label{sec:sock_gethostbyname}
-
-Dato che la principale funzionalità del \textit{resolver} resta quella di
-risolvere i nomi a dominio in indirizzi IP, vedremo per prime le funzioni a
-questo dedicate. La prima funzione è \funcd{gethostbyname} il cui scopo è
-ottenere l'indirizzo di una stazione noto il suo nome a dominio, il suo
-prototipo è:
-\begin{prototype}{netdb.h}
-{struct hostent *gethostbyname(const char *name)}
-
-Determina l'indirizzo associato al nome a dominio \param{name}.
-
-\bodydesc{La funzione restituisce in caso di successo il puntatore ad una
-  struttura di tipo \struct{hostent} contente i dati associati al nome a
-  dominio o un puntatore nullo in caso di errore.}
-\end{prototype}
+\conffile{/etc/hosts}.
+
+Per questo aspetto il file di configurazione principale del sistema è
+\conffile{/etc/resolv.conf} che contiene in sostanza l'elenco degli indirizzi
+IP dei server DNS da contattare; a questo si affiancava (fino alla \acr{glibc}
+2.4) il file \conffile{/etc/host.conf} il cui scopo principale era indicare
+l'ordine in cui eseguire la risoluzione dei nomi (se usare prima i valori di
+\conffile{/etc/hosts} o quelli del DNS). Tralasciamo i dettagli relativi alle
+varie direttive che possono essere usate in questi file, che si trovano nelle
+rispettive pagine di manuale.
+
+Con il tempo però è divenuto possibile fornire diversi sostituti per
+l'utilizzo delle associazione statiche in \conffile{/etc/hosts}, inoltre oltre
+alla risoluzione dei nomi a dominio ci sono anche altri nomi da risolvere,
+come quelli che possono essere associati ad una rete (invece che ad una
+singola macchina) o ai gruppi di macchine definiti dal servizio
+NIS,\footnote{il \textit{Network Information Service} è un servizio, creato da
+  Sun, e poi diffuso su tutte le piattaforme unix-like, che permette di
+  raggruppare all'interno di una rete (in quelli che appunto vengono chiamati
+  \textit{netgroup}) varie macchine, centralizzando i servizi di definizione
+  di utenti e gruppi e di autenticazione, oggi è sempre più spesso sostituito
+  da LDAP.} o come quelli dei protocolli e dei servizi che sono mantenuti nei
+file statici \conffile{/etc/protocols} e \conffile{/etc/services}.  
+
+Molte di queste informazioni non si trovano su un DNS, ma in una rete locale
+può essere molto 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 \conffile{/etc/hosts}, che con il DNS, che con NIS) comporta il
+problema dell'ordine in cui questi vengono interrogati. Con le implementazioni
+classiche i vari supporti erano introdotti modificando direttamente le
+funzioni di libreria, prevedendo un ordine di interrogazione predefinito e non
+modificabile (a meno di una ricompilazione delle librerie stesse).
+
+\itindbeg{Name~Service~Switch~(NSS)} 
+
+Per risolvere questa serie di problemi la risoluzione dei nomi a dominio
+eseguità 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}, cui abbiamo accennato anche in
+sez.~\ref{sec:sys_user_group} per quanto riguarda la gestione dei dati
+associati a utenti e gruppi. Il sistema è stato introdotto la prima volta
+nella libreria standard di Solaris e la \acr{glibc} ha ripreso lo stesso
+schema; si tenga presente che questo sistema non esiste per altre librerie
+standard come la \acr{libc5} o la \acr{uClib}.
+
+Il \textit{Name Service Switch} (cui spesso si fa riferimento con l'acronimo
+NSS) è un sistema di librerie dinamiche che permette di definire in maniera
+generica sia i supporti su cui mantenere i dati di corrispondenza fra nomi e
+valori numerici, sia l'ordine in cui effettuare le ricerche sui vari supporti
+disponibili. Il sistema prevede una serie di possibili classi di
+corrispondenza, quelle attualmente definite sono riportate in
+tab.~\ref{tab:sys_NSS_classes}.
+
+\begin{table}[htb]
+  \footnotesize
+  \centering
+  \begin{tabular}[c]{|l|p{8cm}|}
+    \hline
+    \textbf{Classe} & \textbf{Tipo di corrispondenza}\\
+    \hline
+    \hline
+    \texttt{passwd}   & Corrispondenze fra nome dell'utente e relative
+                        proprietà (\ids{UID}, gruppo principale, ecc.).\\  
+    \texttt{shadow}   & Corrispondenze fra username e password dell'utente
+                        (e altre informazioni relative alle password).\\  
+    \texttt{group}    & Corrispondenze fra nome del gruppo e proprietà dello 
+                        stesso.\\  
+    \texttt{aliases}  & Alias per la posta elettronica.\\ 
+    \texttt{ethers}   & Corrispondenze fra numero IP e MAC address della
+                        scheda di rete.\\ 
+    \texttt{hosts}    & Corrispondenze fra nome a dominio e numero IP.\\ 
+    \texttt{netgroup} & Corrispondenze fra gruppo di rete e macchine che lo
+                        compongono.\\  
+    \texttt{networks} & Corrispondenze fra nome di una rete e suo indirizzo
+                        IP.\\  
+    \texttt{protocols}& Corrispondenze fra nome di un protocollo e relativo
+                        numero identificativo.\\ 
+    \texttt{rpc}      & Corrispondenze fra nome di un servizio RPC e relativo 
+                        numero identificativo.\\ 
+    \texttt{publickey}& Chiavi pubbliche e private usate per gli RFC sicuri,
+                        utilizzate da NFS e NIS+. \\ 
+    \texttt{services} & Corrispondenze fra nome di un servizio e numero di
+                        porta. \\ 
+    \hline
+  \end{tabular}
+  \caption{Le diverse classi di corrispondenze definite
+    all'interno del \textit{Name Service Switch}.} 
+  \label{tab:sys_NSS_classes}
+\end{table}
+
+% TODO rivedere meglio la tabella
+
+Il sistema del \textit{Name Service Switch} è controllato dal contenuto del
+file \conffile{/etc/nsswitch.conf}; questo contiene una riga di configurazione
+per ciascuna di queste classi, che viene inizia col nome di
+tab.~\ref{tab:sys_NSS_classes} seguito da un carattere ``\texttt{:}'' e
+prosegue con la lista dei \textsl{servizi} su cui le relative informazioni
+sono raggiungibili, scritti nell'ordine in cui si vuole siano interrogati.
+Pertanto nelle versioni recenti delle librerie è questo file e non
+\conffile{/etc/host.conf}  a indicare l'ordine con cui si esegue la
+risoluzione dei nomi.
+
+Ogni servizio è specificato a sua volta da un nome, come \texttt{file},
+\texttt{dns}, \texttt{db}, ecc.  che identifica la libreria dinamica che
+realizza l'interfaccia con esso. Per ciascun servizio se \texttt{NAME} è il
+nome utilizzato dentro \conffile{/etc/nsswitch.conf}, dovrà essere presente
+(usualmente in \file{/lib}) una libreria \texttt{libnss\_NAME} che ne
+implementa le funzioni.
+
+In ogni caso, qualunque sia la modalità con cui ricevono i dati o il supporto
+su cui vengono mantenuti, e che si usino o meno funzionalità aggiuntive
+fornite dal sistema del \textit{Name Service Switch}, dal punto di vista di un
+programma che deve effettuare la risoluzione di un nome a dominio, tutto
+quello che conta sono le funzioni classiche che il \textit{resolver} mette a
+disposizione (è cura della \acr{glibc} tenere conto della presenza del
+\textit{Name Service Switch}) e sono queste quelle che tratteremo nelle
+sezioni successive.  
+
+\itindend{Name~Service~Switch~(NSS)}
+
+
+\subsection{Le funzioni di interrogazione del DNS}
+\label{sec:sock_resolver_functions}
+
+Prima di trattare le funzioni usate normalmente nella risoluzione dei nomi a
+dominio conviene trattare in maniera più dettagliata il servizio DNS. Come
+accennato questo, benché esso 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. Inolte esso può fornire anche
+ulteriori informazioni oltre relative alla risoluzione dei nomi a dominio.
+Per questo motivo esistono una serie di funzioni di libreria che servono
+specificamente ad eseguire delle interrogazioni verso un server DNS, funzioni
+che poi vengono utilizzate anche per realizzare le funzioni generiche di
+libreria usate dal sistema del \textit{resolver}.
+
+Il sistema del DNS è in sostanza di un database distribuito organizzato in
+maniera gerarchica, i dati vengono mantenuti in tanti server distinti ciascuno
+dei quali si occupa della risoluzione del proprio \textsl{dominio}; i nomi a
+dominio sono organizzati in una struttura ad albero analoga a quella
+dell'albero dei file, con domini di primo livello (come i \texttt{.org}),
+secondo livello (come \texttt{.truelite.it}), ecc.  In questo caso le
+separazioni sono fra i vari livelli sono definite dal carattere ``\texttt{.}''
+ed i nomi devono essere risolti da destra verso sinistra.\footnote{per chi si
+  stia chiedendo quale sia la radice di questo albero, cioè l'equivalente di
+  ``\texttt{/}'', la risposta è il dominio speciale ``\texttt{.}'', che in
+  genere non viene mai scritto esplicitamente, ma che, come chiunque abbia
+  configurato un server DNS sa bene, esiste ed è gestito dai cosiddetti
+  \textit{root DNS} che risolvono i domini di primo livello.} Il meccanismo
+funziona con il criterio della \textsl{delegazione}, un server responsabile
+per un dominio di primo livello può delegare la risoluzione degli indirizzi
+per un suo dominio di secondo livello ad un altro server, il quale a sua volta
+potrà delegare la risoluzione di un eventuale sotto-dominio di terzo livello ad
+un altro server ancora.
+
+Come accennato un server DNS è in grado di fare molto altro rispetto alla
+risoluzione di un nome a dominio in un indirizzo IP: ciascuna voce nel
+database viene chiamata \textit{resource record}, e può contenere diverse
+informazioni. In genere i \textit{resource record} vengono classificati per la
+\textsl{classe di indirizzi} cui i dati contenuti fanno riferimento, e per il
+\textsl{tipo} di questi ultimi (ritroveremo classi di indirizzi e tipi di
+record più avanti in tab.~\ref{tab:DNS_address_class} e
+tab.~\ref{tab:DNS_record_type}).  Oggigiorno i dati mantenuti nei server DNS
+sono quasi esclusivamente relativi ad indirizzi internet, per cui in pratica
+viene utilizzata soltanto una classe di indirizzi; invece le corrispondenze
+fra un nome a dominio ed un indirizzo IP sono solo uno fra i vari tipi di
+informazione che un server DNS fornisce normalmente.
+
+L'esistenza di vari tipi di informazioni è un altro dei motivi per cui il
+\textit{resolver} prevede, oltre a quelle relative alla semplice risoluzione
+dei nomi, un insieme di funzioni specifiche dedicate all'interrogazione di un
+server DNS, tutte nella forma \texttt{res\_}\textsl{\texttt{nome}}. La prima
+di queste funzioni è \funcd{res\_init}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{netinet/in.h} 
+\fhead{arpa/nameser.h} 
+\fhead{resolv.h}
+\fdecl{int res\_init(void)}
+\fdesc{Inizializza il sistema del \textit{resolver}.} 
+}
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore.
+}
+\end{funcproto}
+
+La funzione legge il contenuto dei file di configurazione per impostare il
+dominio di default, gli indirizzi dei server DNS da contattare e l'ordine
+delle ricerche; se non sono specificati server verrà utilizzato l'indirizzo
+locale, e se non è definito un dominio di default sarà usato quello associato
+con l'indirizzo locale (ma questo può essere sovrascritto con l'uso della
+variabile di ambiente \envvar{LOCALDOMAIN}). In genere non è necessario
+eseguire questa funzione esplicitamente, in quanto viene automaticamente
+chiamata la prima volta che si esegue una qualunque delle altre.
+
+Le impostazioni e lo stato del \textit{resolver} inizializzati da
+\func{res\_init} vengono mantenuti in una serie di variabili raggruppate nei
+campi di una apposita struttura. Questa struttura viene definita in
+\headfiled{resolv.h} e mantenuta nella variabile globale \var{\_res}, che
+viene utilizzata internamente da tutte le funzioni dell'interfaccia. Questo
+consente anche di accedere direttamente al contenuto della variabile
+all'interno di un qualunque programma, una volta che la sia opportunamente
+dichiarata con:
+\includecodesnip{listati/resolv_option.c}
+
+Dato che l'uso di una variabile globale rende tutte le funzioni
+dell'interfaccia classica non rientranti, queste sono state deprecate in
+favore di una nuova interfaccia in cui esse sono state sostituite da
+altrettante nuove funzioni, il cui nome è ottenuto apponendo una
+``\texttt{n}'' al nome di quella tradizionale (cioè nella forma
+\texttt{res\_n\textsl{nome}}). Tutte le nuove funzioni sono identiche alle
+precedenti, ma hanno un primo argomento aggiuntivo, \param{statep}, puntatore
+ad una struttura dello stesso tipo di \var{\_res}. Questo consente di usare
+una variabile locale per mantenere lo stato del \textit{resolver}, rendendo le
+nuove funzioni rientranti.  In questo caso per poter utilizzare il nuovo
+argomento occorrerà una opportuna dichiarazione del relativo tipo di dato con:
+\includecodesnip{listati/resolv_newoption.c}
+
+Così la nuova funzione utilizzata per inizializzare il \textit{resolver} (che
+come la precedente viene chiamata automaticamente da tutte altre funzioni) è
+\funcd{res\_ninit}, ed il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{netinet/in.h} 
+\fhead{arpa/nameser.h} 
+\fhead{resolv.h}
+\fdecl{int res\_ninit(res\_state statep)}
+\fdesc{Inizializza il sistema del \textit{resolver}.} 
+}
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore.
+}
+\end{funcproto}
+
+Indipendentemente da quale versione delle funzioni si usino, tutti i campi
+della struttura (\var{\_res} o la variabile puntata da \param{statep}) sono ad
+uso interno, e vengono usualmente inizializzate da \func{res\_init} o
+\func{res\_ninit} in base al contenuto dei file di configurazione e ad una
+serie di valori di default. L'unico campo che può essere utile modificare è
+\var{\_res.options} (o l'equivalente della variabile puntata
+da\param{statep}), una maschera binaria che contiene una serie di bit che
+esprimono le opzioni che permettono di controllare il comportamento del
+\textit{resolver}.
+
+\begin{table}[htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|p{8cm}|}
+    \hline
+    \textbf{Costante} & \textbf{Significato} \\
+    \hline
+    \hline
+    \constd{RES\_INIT}       & Viene attivato se è stata chiamata
+                               \func{res\_init}. \\
+    \constd{RES\_DEBUG}      & Stampa dei messaggi di debug.\\
+    \constd{RES\_AAONLY}     & Accetta solo risposte autoritative.\\
+    \constd{RES\_USEVC}      & Usa connessioni TCP per contattare i server 
+                               invece che l'usuale UDP.\\
+    \constd{RES\_PRIMARY}    & Interroga soltanto server DNS primari.\\
+    \constd{RES\_IGNTC}      & Ignora gli errori di troncamento, non ritenta la
+                               richiesta con una connessione TCP.\\
+    \constd{RES\_RECURSE}    & Imposta il bit che indica che si desidera
+                               eseguire una interrogazione ricorsiva.\\
+    \constd{RES\_DEFNAMES}   & Se attivo \func{res\_search} aggiunge il nome
+                               del dominio di default ai nomi singoli (che non
+                               contengono cioè un ``\texttt{.}'').\\
+    \constd{RES\_STAYOPEN}   & Usato con \const{RES\_USEVC} per mantenere
+                               aperte le connessioni TCP fra interrogazioni
+                               diverse.\\
+    \constd{RES\_DNSRCH}     & Se attivo \func{res\_search} esegue le ricerche
+                               di nomi di macchine nel dominio corrente o nei
+                               domini ad esso sovrastanti.\\
+    \constd{RES\_INSECURE1}  & Blocca i controlli di sicurezza di tipo 1.\\
+    \constd{RES\_INSECURE2}  & Blocca i controlli di sicurezza di tipo 2.\\
+    \constd{RES\_NOALIASES}  & Blocca l'uso della variabile di ambiente
+                               \envvar{HOSTALIASES}.\\ 
+    \constd{RES\_USE\_INET6} & Restituisce indirizzi IPv6 con
+                               \func{gethostbyname}. \\
+    \constd{RES\_ROTATE}     & Ruota la lista dei server DNS dopo ogni
+                               interrogazione.\\
+    \constd{RES\_NOCHECKNAME}& Non controlla i nomi per verificarne la
+                               correttezza sintattica. \\
+    \constd{RES\_KEEPTSIG}   & Non elimina i record di tipo \texttt{TSIG}.\\
+    \constd{RES\_BLAST}      & Effettua un ``\textit{blast}'' inviando
+                               simultaneamente le richieste a tutti i server;
+                               non ancora implementata. \\
+    \constd{RES\_DEFAULT}    & Combinazione di \const{RES\_RECURSE},
+                               \const{RES\_DEFNAMES} e \const{RES\_DNSRCH}.\\
+    \hline
+  \end{tabular}
+  \caption{Costanti utilizzabili come valori per \var{\_res.options}.}
+  \label{tab:resolver_option}
+\end{table}
+
+Per utilizzare questa funzionalità per modificare le impostazioni direttamente
+da programma occorrerà impostare un opportuno valore per questo campo ed
+invocare esplicitamente \func{res\_init} o \func{res\_ninit}, dopo di che le
+altre funzioni prenderanno le nuove impostazioni. Le costanti che definiscono
+i vari bit di questo campo, ed il relativo significato sono illustrate in
+tab.~\ref{tab:resolver_option}; trattandosi di una maschera binaria un valore
+deve essere espresso con un opportuno OR aritmetico di dette costanti; ad
+esempio il valore di default delle opzioni, espresso dalla costante
+\const{RES\_DEFAULT}, è definito come:
+\includecodesnip{listati/resolv_option_def.c}
+
+Non tratteremo il significato degli altri campi non essendovi necessità di
+modificarli direttamente; gran parte di essi sono infatti impostati dal
+contenuto dei file di configurazione, mentre le funzionalità controllate da
+alcuni di esse possono essere modificate con l'uso delle opportune variabili
+di ambiente come abbiamo visto per \envvar{LOCALDOMAIN}. In particolare con
+\envvar{RES\_RETRY} si soprassiede il valore del campo \var{retry} che
+controlla quante volte viene ripetuto il tentativo di connettersi ad un server
+DNS prima di dichiarare fallimento; il valore di default è 4, un valore nullo
+significa bloccare l'uso del DNS. Infine con \envvar{RES\_TIMEOUT} si
+soprassiede il valore del campo \var{retrans} (preimpostato al valore della
+omonima costante \const{RES\_TIMEOUT} di \headfile{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 raddoppiando
+il tempo di scadenza per il numero massimo di volte stabilito da
+\texttt{RES\_RETRY}.
+
+La funzione di interrogazione principale è \funcd{res\_query}
+(\funcd{res\_nquery} per la nuova interfaccia), che serve ad eseguire una
+richiesta ad un server DNS per un nome a dominio \textsl{completamente
+  specificato} (quello che si chiama
+\itindex{Fully~Qualified~Domain~Name~(FQDN)} FQDN, \textit{Fully Qualified 
+  Domain Name}); il loro prototipo è:
+
+\begin{funcproto}{
+\fhead{netinet/in.h} 
+\fhead{arpa/nameser.h} 
+\fhead{resolv.h}
+\fdecl{int res\_query(const char *dname, int class, int type,
+              unsigned char *answer, int anslen)}
+\fdecl{int res\_nquery(res\_state statep, const char *dname, int class, int
+  type, \\
+  \phantom{int res\_nquery(}unsigned char *answer, int anslen)}
+\fdesc{Esegue una interrogazione al DNS.} 
+}
+{Le funzioni ritornano un valore positivo pari alla lunghezza dei dati scritti
+  nel buffer \param{answer} in caso di successo e $-1$ per un errore.
+}
+\end{funcproto}
+
+Le funzioni eseguono una interrogazione ad un server DNS relativa al nome da
+risolvere passato nella stringa indirizzata da \param{dname}, inoltre deve
+essere specificata la classe di indirizzi in cui eseguire la ricerca con
+\param{class}, ed il tipo di \textit{resource record} che si vuole ottenere
+con \param{type}. Il risultato della ricerca verrà scritto nel buffer di
+lunghezza \param{anslen} puntato da \param{answer} che si sarà opportunamente
+allocato in precedenza.
+
+Una seconda funzione di ricerca analoga a \func{res\_query}, che prende gli
+stessi argomenti ma che esegue l'interrogazione con le funzionalità
+addizionali previste dalle due opzioni \const{RES\_DEFNAMES} e
+\const{RES\_DNSRCH}, è \funcd{res\_search} (\funcd{res\_nsearch} per la nuova
+interfaccia), il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{netinet/in.h} 
+\fhead{arpa/nameser.h} 
+\fhead{resolv.h}
+\fdecl{int res\_search(const char *dname, int class, int type,
+  unsigned char *answer, \\
+  \phantom{int res\_search}int anslen)}
+\fdecl{int res\_nsearch(res\_state statep, const char *dname, int class, 
+  int type, \\
+  \phantom{int res\_nsearch(}unsigned char *answer, int anslen)}
+\fdesc{Esegue una interrogazione al DNS.} 
+}
+{Le funzioni ritornano un valore positivo pari alla lunghezza dei dati scritti
+  nel buffer \param{answer} in caso di successo e $-1$ per un errore.
+}
+\end{funcproto}
+
+In sostanza la funzione ripete una serie di chiamate a \func{res\_query}
+(\func{res\_nquery}) aggiungendo al nome contenuto nella stringa \param{dname}
+il dominio di default da cercare, fermandosi non appena trova un risultato.
+Il risultato di entrambe le funzioni viene scritto nel formato opportuno (che
+sarà diverso a seconda del tipo di record richiesto) nel buffer di ritorno;
+sarà compito del programma (o di altre funzioni) estrarre i relativi dati,
+esistono una serie di funzioni interne usate per la scansione di questi dati,
+per chi fosse interessato una trattazione dettagliata è riportata nel
+quattordicesimo capitolo di \cite{DNSbind}.
+
+Le classi di indirizzi supportate da un server DNS sono tre, ma di queste in
+pratica oggi viene utilizzata soltanto quella degli indirizzi internet; le
+costanti che identificano dette classi, da usare come valore per l'argomento
+\param{class} delle precedenti funzioni, sono riportate in
+tab.~\ref{tab:DNS_address_class} (esisteva in realtà anche una classe
+\constd{C\_CSNET} per la omonima rete, ma è stata dichiarata obsoleta).
+
+\begin{table}[htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|p{8cm}|}
+    \hline
+    \textbf{Costante} & \textbf{Significato} \\
+    \hline
+    \hline
+    \constd{C\_IN}   & Indirizzi internet, in pratica i soli utilizzati oggi.\\
+    \constd{C\_HS}   & Indirizzi \textit{Hesiod}, utilizzati solo al MIT, oggi
+                       completamente estinti. \\
+    \constd{C\_CHAOS}& Indirizzi per la rete \textit{Chaosnet}, un'altra rete
+                       sperimentale nata al MIT. \\
+    \constd{C\_ANY}  & Indica un indirizzo di classe qualunque.\\
+    \hline
+  \end{tabular}
+  \caption{Costanti identificative delle classi di indirizzi per l'argomento
+    \param{class} di \func{res\_query}.}
+  \label{tab:DNS_address_class}
+\end{table}
+
+Come accennato le tipologie di dati che sono mantenibili su un server DNS sono
+diverse, ed a ciascuna di essa corrisponde un diverso tipo di \textit{resource
+  record}. L'elenco delle costanti, ripreso dai file di dichiarazione
+\headfiled{arpa/nameser.h} e \headfiled{arpa/nameser\_compat.h}, che
+definiscono i valori che si possono usare per l'argomento \param{type} per
+specificare il tipo di \textit{resource record} da richiedere è riportato in
+tab.~\ref{tab:DNS_record_type}; le costanti (tolto il \texttt{T\_} iniziale)
+hanno gli stessi nomi usati per identificare i record nei file di zona di
+BIND,\footnote{BIND, acronimo di \textit{Berkley Internet Name Domain}, è una
+  implementazione di un server DNS, ed, essendo utilizzata nella stragrande
+  maggioranza dei casi, fa da 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 costanti di
+  tab.~\ref{tab:DNS_record_type} senza il \texttt{T\_} iniziale.} e che
+normalmente sono anche usati come nomi per indicare i record.
+
+\begin{table}[!htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|l|}
+    \hline
+    \textbf{Costante} & \textbf{Significato} \\
+    \hline
+    \hline
+    \constd{T\_A}     & Indirizzo di una stazione.\\
+    \constd{T\_NS}    & Server DNS autoritativo per il dominio richiesto.\\
+    \constd{T\_MD}    & Destinazione per la posta elettronica.\\
+    \constd{T\_MF}    & Redistributore per la posta elettronica.\\
+    \constd{T\_CNAME} & Nome canonico.\\
+    \constd{T\_SOA}   & Inizio di una zona di autorità.\\
+    \constd{T\_MB}    & Nome a dominio di una casella di posta.\\
+    \constd{T\_MG}    & Nome di un membro di un gruppo di posta.\\
+    \constd{T\_MR}    & Nome di un cambiamento di nome per la posta.\\
+    \constd{T\_NULL}  & Record nullo.\\
+    \constd{T\_WKS}   & Servizio noto.\\
+    \constd{T\_PTR}   & Risoluzione inversa di un indirizzo numerico.\\
+    \constd{T\_HINFO} & Informazione sulla stazione.\\
+    \constd{T\_MINFO} & Informazione sulla casella di posta.\\
+    \constd{T\_MX}    & Server cui instradare la posta per il dominio.\\
+    \constd{T\_TXT}   & Stringhe di testo (libere).\\
+    \constd{T\_RP}    & Nome di un responsabile (\textit{responsible person}).\\
+    \constd{T\_AFSDB} & Database per una cella AFS.\\
+    \constd{T\_X25}   & Indirizzo di chiamata per X.25.\\
+    \constd{T\_ISDN}  & Indirizzo di chiamata per ISDN.\\
+    \constd{T\_RT}    & Router.\\
+    \constd{T\_NSAP}  & Indirizzo NSAP.\\
+    \constd{T\_NSAP\_PTR}& Risoluzione inversa per NSAP (deprecato).\\
+    \constd{T\_SIG}   & Firma digitale di sicurezza.\\
+    \constd{T\_KEY}   & Chiave per firma.\\
+    \constd{T\_PX}    & Corrispondenza per la posta X.400.\\
+    \constd{T\_GPOS}  & Posizione geografica.\\
+    \constd{T\_AAAA}  & Indirizzo IPv6.\\
+    \constd{T\_LOC}   & Informazione di collocazione.\\
+    \constd{T\_NXT}   & Dominio successivo.\\
+    \constd{T\_EID}   & Identificatore di punto conclusivo.\\
+    \constd{T\_NIMLOC}& Posizionatore \textit{nimrod}.\\
+    \constd{T\_SRV}   & Servizio.\\
+    \constd{T\_ATMA}  & Indirizzo ATM.\\
+    \constd{T\_NAPTR} & Puntatore ad una \textit{naming authority}.\\
+    \constd{T\_TSIG}  & Firma di transazione.\\
+    \constd{T\_IXFR}  & Trasferimento di zona incrementale.\\
+    \constd{T\_AXFR}  & Trasferimento di zona di autorità.\\
+    \constd{T\_MAILB} & Trasferimento di record di caselle di posta.\\
+    \constd{T\_MAILA} & Trasferimento di record di server di posta.\\
+    \constd{T\_ANY}   & Valore generico.\\
+    \hline
+  \end{tabular}
+  \caption{Costanti identificative del tipo di record per l'argomento
+    \param{type} di \func{res\_query}.}
+  \label{tab:DNS_record_type}
+\end{table}
+
+
+L'elenco di tab.~\ref{tab:DNS_record_type} è quello di \textsl{tutti} i
+\textit{resource record} definiti, con una breve descrizione del relativo
+significato.  Di tutti questi però viene impiegato correntemente solo un
+piccolo sottoinsieme, alcuni sono obsoleti ed altri fanno riferimento a dati
+applicativi che non ci interessano non avendo nulla a che fare con la
+risoluzione degli indirizzi IP, pertanto non entreremo nei dettagli del
+significato di tutti i \textit{resource record}, ma solo di quelli usati dalle
+funzioni del \textit{resolver}. Questi sono sostanzialmente i seguenti (per
+indicarli si è usata la notazione dei file di zona di BIND):
+\begin{basedescript}{\desclabelwidth{1.2cm}\desclabelstyle{\nextlinelabel}}
+\item[\texttt{A}] viene usato per indicare la corrispondenza fra un nome a
+  dominio ed un indirizzo IPv4; ad esempio la corrispondenza fra
+  \texttt{jojo.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 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
+  stesso indirizzo (come ad esempio \texttt{www.truelite.it} e
+  \texttt{sources.truelite.it}, che fanno entrambi riferimento alla stessa
+  macchina (nel caso \texttt{dodds.truelite.it}) si può usare questo tipo di
+  record per creare degli \textit{alias} in modo da associare un qualunque
+  altro nome al \textsl{nome canonico} della macchina (si chiama così quello
+  associato al record \texttt{A}).
+\end{basedescript}
+
+Come accennato in caso di successo le due funzioni di richiesta restituiscono
+il risultato della interrogazione al server, in caso di insuccesso l'errore
+invece viene segnalato da un valore di ritorno pari a $-1$, ma in questo caso,
+non può essere utilizzata la variabile \var{errno} per riportare un codice di
+errore, in quanto questo viene impostato per ciascuna delle chiamate al
+sistema utilizzate dalle funzioni del \textit{resolver}, non avrà alcun
+significato nell'indicare quale parte del procedimento di risoluzione è
+fallita.
+
+Per questo motivo è stata definita una variabile di errore separata,
+\var{h\_errno}, che viene utilizzata dalle funzioni del \textit{resolver} per
+indicare quale problema ha causato il fallimento della risoluzione del nome.
+Ad essa si può accedere una volta che la si dichiara con:
+\includecodesnip{listati/herrno.c} 
+ed i valori che può assumere, con il relativo significato, sono riportati in
+tab.~\ref{tab:h_errno_values}.
+
+\begin{table}[!htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|p{9cm}|}
+    \hline
+    \textbf{Costante} & \textbf{Significato} \\
+    \hline
+    \hline
+    \constd{HOST\_NOT\_FOUND}& L'indirizzo richiesto non è valido e la
+                               macchina indicata è sconosciuta.\\
+    \constd{NO\_ADDRESS}     & Il nome a dominio richiesto è valido, ma non ha
+                               un indirizzo associato ad esso
+                               (alternativamente può essere indicato come 
+                               \constd{NO\_DATA}).\\
+    \constd{NO\_RECOVERY}    & Si è avuto un errore non recuperabile
+                               nell'interrogazione di un server DNS.\\
+    \constd{TRY\_AGAIN}      & Si è avuto un errore temporaneo
+                               nell'interrogazione di un server DNS, si può
+                               ritentare l'interrogazione in un secondo
+                               tempo.\\
+    \hline
+  \end{tabular}
+  \caption{Valori possibili della variabile \var{h\_errno}.}
+  \label{tab:h_errno_values}
+\end{table}
+
+Insieme alla nuova variabile vengono definite anche delle nuove funzioni per
+stampare l'errore a video, analoghe a quelle di sez.~\ref{sec:sys_strerror}
+per \var{errno}, ma che usano il valore di \var{h\_errno}; la prima è
+\funcd{herror} ed il suo prototipo è:
+
+{\centering
+\vspace{3pt}
+\begin{funcbox}{
+\fhead{netdb.h}
+\fdecl{void herror(const char *string)}
+\fdesc{Stampa un errore di risoluzione.} 
+}
+\end{funcbox}}
+
+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 è:
+
+{\centering
+\vspace{3pt}
+\begin{funcbox}{
+\fhead{netdb.h}
+\fdecl{const char *hstrerror(int err)}
+\fdesc{Restituisce una stringa corrispondente ad un errore di risoluzione.}
+}
+\end{funcbox}}
+
+\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}).
+
+\itindend{resolver}
+
+
+\subsection{La vecchia interfaccia per la risoluzione dei nomi a dominio}
+\label{sec:sock_name_services}
+
+La principale funzionalità del \textit{resolver} resta quella di risolvere i
+nomi a dominio in indirizzi IP, per cui non ci dedicheremo oltre alle funzioni
+per effetture delle richieste generiche al DNS ed esamineremo invece le
+funzioni del \textit{resolver} dedicate specificamente a questo. Tratteremo in
+questa sezione l'interfaccia tradizionale, che ormai è deprecata, mentre
+vedremo nella sezione seguente la nuova interfaccia.
+
+La prima funzione dell'interfaccia tradizionale è \funcd{gethostbyname} il cui
+scopo è ottenere l'indirizzo di una stazione noto il suo nome a dominio, il
+suo prototipo è:
+
+\begin{funcproto}{
+\fhead{netdb.h}
+\fdecl{struct hostent *gethostbyname(const char *name)}
+\fdesc{Determina l'indirizzo associato ad un nome a dominio.} 
+}
+
+{La funzione ritorna il puntatore ad una
+  struttura di tipo \struct{hostent} contenente i dati associati al nome a
+  dominio in caso di successo o un puntatore nullo per un errore.}
+\end{funcproto}
 
 La funzione prende come argomento una stringa \param{name} contenente il nome
 a dominio che si vuole risolvere, in caso di successo i dati ad esso relativi
 vengono memorizzati in una opportuna struttura \struct{hostent} la cui
-definizione è riportata in fig.~\ref{fig:sock_hostent_struct}. In caso di
-insuccesso l'errore viene segnalato da un valore nullo del puntatore, ma in
-questo caso, a differenza delle funzioni viste finora, non viene utilizzata la
-variabile \var{errno} per riportare un codice di errore, in quanto questo è
-dipende solo dalle sottostanti chiamate al sistema e non avere nessun
-significato nell'indicare quale parte del procedimento di risoluzione è
-fallita.
+definizione è riportata in fig.~\ref{fig:sock_hostent_struct}. 
 
 \begin{figure}[!htb]
   \footnotesize \centering
-  \begin{minipage}[c]{15cm}
+  \begin{minipage}[c]{0.80\textwidth}
     \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}
 
-Per questo motivo all'interno del resolver è stata definita una apposita
-variabile di errore, \var{h\_errno} che viene utilizzata dalle funzioni di
-libreria per indicare quale problema ha causato il fallimento della
-risoluzione. Ad essa si può accedere una volta che la si dichiara con:
-\includecodesnip{listati/herrno.c}
-ed i valori che può assumere sono i seguenti:
-\begin{basedescript}{\desclabelwidth{3cm}\desclabelstyle{\nextlinelabel}}
-\item[\const{HOST\_NOT\_FOUND}] l'indirizzo richiesto non è valido e la
-  macchina indicata è sconosciuta.
-\item[\const{NO\_ADDRESS}] il nome a dominio richiesto è valido, ma non ha un
-  indirizzo associato ad esso.
-\item[\const{NO\_RECOVERY}] si è avuto un errore non recuperabile
-  nell'interrogazione di un server DNS.
-\item[\const{TRY\_AGAIN}] si è avuto un errore temporaneo nell'interrogazione
-  di un server DNS, si può ritentare l'interrogazione in un secondo tempo. 
-\end{basedescript}
+Quando un programma chiama \func{gethostbyname} e questa usa il DNS per
+effettuare la risoluzione del nome, è con i valori contenuti nei relativi
+record che vengono riempite le varie parti della struttura \struct{hostent}.
+Il primo campo della struttura, \var{h\_name} contiene sempre il \textsl{nome
+  canonico}, che nel caso del DNS è appunto il nome associato ad un record
+\texttt{A}. Il secondo campo della struttura, \var{h\_aliases}, invece è un
+puntatore ad vettore di puntatori, terminato da un puntatore nullo. Ciascun
+puntatore del vettore punta ad una stringa contenente uno degli altri
+possibili nomi associati allo stesso \textsl{nome canonico} (quelli che nel
+DNS vengono inseriti come record di tipo \texttt{CNAME}).
 
+Il terzo campo della struttura, \var{h\_addrtype}, indica il tipo di indirizzo
+che è stato restituito, e può assumere soltanto i valori \const{AF\_INET} o
+\const{AF\_INET6}, mentre il quarto campo, \var{h\_length}, indica la
+lunghezza dell'indirizzo stesso in byte. 
 
-Per capire meglio il contenuto della struttura \struct{hostent} conviene
-spendere alcune parole sul funzionamento del DNS. Questo in sostanza è un
-enorme database distribuito interrogando il quale si possono avere una serie
-di informazioni la principale delle quali è la corrispondenza fra un nome (a
-dominio) ed indirizzo IP.  Un server DNS contiene comunque una serie di altre
-informazioni; ciascuna voce nel database viene chiamata \textit{resource
-  record} e vi è associato un certo \textsl{tipo}, identificato da una sigla.
-Per quanto ci interessa i \textit{resource record} che vengono utilizzati dal
-\textit{resolver} sono sostanzialmente i seguenti:
-\begin{basedescript}{\desclabelwidth{1.2cm}\desclabelstyle{\nextlinelabel}}
-\item[\texttt{A}] indica la corripondenza fra un nome a dominio ed un
-  indirizzo IPv4, ad esempio la corrispondenza fra \texttt{dodds.truelite.it}
-  e l'indirizzo IP \texttt{62.48.34.25}.
-\item[\texttt{AAAA}] chiamato in questo modo dato che la dimensione è quattro
-  volte quella di un indirizzo IPv4, questo record contiene la corrispondenza
-  fra un nome a dominio ed un indirizzo IPv6.
-\item[\texttt{PTR}] per provvedere la mappatura inversa fra un indirizzo IP ed
-  un nome a dominio si utilizza invece questo tipo di record (il cui nome sta
-  per \textit{pointer}).
-\item[\texttt{CNAME}] qualora si abbiamo più nomi con i quali si voglia
-  indicare lo stesso indirizzo (ad esempio \texttt{www.truelite.it}, o
-  \texttt{sources.truelite.it}, che comunque fanno sempre riferimento alla
-  macchina \texttt{dodds.truelite.it}) si può usare questo tipo di record per
-  creare degli \textit{alias} in modo da associare un qualunque altro nome al
-  \textsl{nome canonico} della macchina (quello associato al record
-  \texttt{A}).
-\end{basedescript}
+Infine il campo \var{h\_addr\_list} è il puntatore ad un vettore di puntatori
+ai singoli indirizzi; il vettore è terminato da un puntatore nullo.  Inoltre,
+come illustrato in fig.~\ref{fig:sock_hostent_struct}, viene definito il campo
+\var{h\_addr} come sinonimo di \code{h\_addr\_list[0]}, cioè un riferimento
+diretto al primo indirizzo della lista.
 
-Quando un programma chiama \func{gethostbyname} e questa usa il DNS per
-effettuare la risoluzione del nome, è con i valori di questi record che
-vengono riempite le varie parti della struttura \struct{hostent}. Il primo
-campo della struttura, \var{h\_name} contiene sempre il \textsl{nome
-  canonico}, che nel caso del DNS è appunto il nome associato ad un record
-\texttt{A}. Il secondo campo della struttura invece è un puntatore ad vettore
-di puntatori, terminato da un puntatore nullo, alle strighe che contengono
-tutti i possibili altri nomi (quelli che nel DNS sarebbero record
-\texttt{CNAME}).
+Oltre ai normali nomi a dominio la funzione accetta come argomento
+\param{name} anche indirizzi numerici, in formato dotted decimal per IPv4 o
+con la notazione illustrata in sez.~\ref{sec:IP_ipv6_notation} per IPv6. In
+tal caso \func{gethostbyname} non eseguirà nessuna interrogazione remota, ma
+si limiterà a copiare la stringa nel campo \var{h\_name} ed a creare la
+corrispondente struttura \var{in\_addr} da indirizzare con
+\code{h\_addr\_list[0]}.
+
+Con l'uso di \func{gethostbyname} si ottengono solo gli indirizzi IPv4, se si
+vogliono ottenere degli indirizzi IPv6 occorrerà prima impostare l'opzione
+\const{RES\_USE\_INET6} nel campo \texttt{\_res.options} e poi chiamare
+\func{res\_init} (vedi sez.~\ref{sec:sock_resolver_functions}) per modificare
+le opzioni del \textit{resolver}; dato che questo non è molto comodo è stata
+definita (è una estensione fornita dalla \acr{glibc}, disponibile anche in
+altri sistemi unix-like) un'altra funzione, \funcd{gethostbyname2}, il cui
+prototipo è:
+
+\begin{funcproto}{
+\fhead{netdb.h}
+\fhead{sys/socket.h}
+\fdecl{struct hostent *gethostbyname2(const char *name, int af)}
+\fdesc{Determina l'indirizzo del tipo scelto associato ad un nome a dominio.} 
+}
+
+{La funzione ritorna il puntatore ad una
+  struttura di tipo \struct{hostent} contenente i dati associati al nome a
+  dominio in caso di successo e  un puntatore nullo per un errore.}
+\end{funcproto}
+
+In questo caso la funzione prende un secondo argomento \param{af} che indica
+quale famiglia di indirizzi è quella che dovrà essere utilizzata per
+selezionare i risultati restituiti dalla funzione; i soli valori consentiti
+sono \const{AF\_INET} o \const{AF\_INET6} per indicare rispettivamente IPv4 e
+IPv6 (per questo è necessario l'uso di \headfile{sys/socket.h}). Per tutto il
+resto la funzione è identica a \func{gethostbyname}, ed identici sono i suoi
+risultati.
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{\codesamplewidth}
+    \includecodesample{listati/mygethost.c}
+  \end{minipage}
+  \normalsize
+  \caption{Esempio di codice per la risoluzione di un indirizzo.}
+  \label{fig:mygethost_example}
+\end{figure}
+
+Vediamo allora un primo esempio dell'uso delle funzioni di risoluzione, in
+fig.~\ref{fig:mygethost_example} è riportato un estratto del codice di un
+programma che esegue una semplice interrogazione al \textit{resolver} usando
+\func{gethostbyname} e poi ne stampa a video i risultati. Al solito il
+sorgente completo, che comprende il trattamento delle opzioni ed una funzione
+per stampare un messaggio di aiuto, è nel file \texttt{mygethost.c} dei
+sorgenti allegati alla guida.
+
+Il programma richiede un solo argomento che specifichi il nome da cercare,
+senza il quale (\texttt{\small 15--18}) esce con un errore. Dopo di che
+(\texttt{\small 20}) si limita a chiamare \func{gethostbyname}, ricevendo il
+risultato nel puntatore \var{data}. Questo (\texttt{\small 21--24}) viene
+controllato per rilevare eventuali errori, nel qual caso il programma esce
+dopo aver stampato un messaggio con \func{herror}. 
+
+Se invece la risoluzione è andata a buon fine si inizia (\texttt{\small 25})
+con lo stampare il nome canonico, dopo di che (\texttt{\small 26--30}) si
+stampano eventuali altri nomi. Per questo prima (\texttt{\small 26}) si prende
+il puntatore alla cima della lista che contiene i nomi e poi (\texttt{\small
+  27--30}) si esegue un ciclo che sarà ripetuto fin tanto che nella lista si
+troveranno dei puntatori validi per le stringhe dei nomi (si ricordi che la
+lista viene terminata da un puntatore nullo); prima (\texttt{\small 28}) si
+stamperà la stringa e poi (\texttt{\small 29}) si provvederà ad incrementare
+il puntatore per passare al successivo elemento della lista.
+
+Una volta stampati i nomi si passerà a stampare gli indirizzi, il primo passo
+(\texttt{\small 31--38}) è allora quello di riconoscere il tipo di indirizzo
+sulla base del valore del campo \var{h\_addrtype}, stampandolo a video. Si è
+anche previsto di stampare un errore nel caso (che non dovrebbe mai accadere)
+di un indirizzo non valido.
+
+Infine (\texttt{\small 39--44}) si stamperanno i valori degli indirizzi, di
+nuovo (\texttt{\small 39}) si inizializzerà un puntatore alla cima della lista
+e si eseguirà un ciclo fintanto che questo punterà ad indirizzi validi in
+maniera analoga a quanto fatto in precedenza per i nomi a dominio. Si noti
+come, essendo il campo \var{h\_addr\_list} un puntatore ad strutture di
+indirizzi generiche, questo sia ancora di tipo \texttt{char **} e si possa
+riutilizzare lo stesso puntatore usato per i nomi.
+
+Per ciascun indirizzo valido si provvederà (\texttt{\small 41}) a una
+conversione con la funzione \func{inet\_ntop} (vedi
+sez.~\ref{sec:sock_addr_func}) passandole gli opportuni argomenti, questa
+restituirà la stringa da stampare (\texttt{\small 42}) con il valore
+dell'indirizzo in \var{buffer}, che si è avuto la cura di dichiarare
+inizialmente (\texttt{\small 10}) con dimensioni adeguate; dato che la
+funzione è in grado di tenere conto automaticamente del tipo di indirizzo non
+ci sono precauzioni particolari da prendere.\footnote{volendo essere pignoli
+  si dovrebbe controllarne lo stato di uscita, lo si è tralasciato per non
+  appesantire il codice, dato che in caso di indirizzi non validi si sarebbe
+  avuto un errore con \func{gethostbyname}, ma si ricordi che la sicurezza non
+  è mai troppa.}
+
+Le funzioni illustrate finora hanno un difetto: utilizzano tutte una area di
+memoria interna per allocare i contenuti della struttura \struct{hostent} e
+per questo non possono essere rientranti. L'uso della memoria interna inoltre
+comporta anche che in due successive chiamate i dati potranno essere
+sovrascritti.
+
+Si tenga presente poi che copiare il contenuto della sola struttura non è
+sufficiente per salvare tutti i dati, in quanto questa contiene puntatori ad
+altri dati, che pure possono essere sovrascritti; per questo motivo, se si
+vuole salvare il risultato di una chiamata, occorrerà eseguire quella che si
+chiama una \itindex{deep~copy} \textit{deep copy}.\footnote{si chiama così
+  quella tecnica per cui, quando si deve copiare il contenuto di una struttura
+  complessa (con puntatori che puntano ad altri dati, che a loro volta possono
+  essere puntatori ad altri dati) si deve copiare non solo il contenuto della
+  struttura, ma eseguire una scansione per risolvere anche tutti i puntatori
+  contenuti in essa (e così via se vi sono altre sotto-strutture con altri
+  puntatori) e copiare anche i dati da questi referenziati.}
+
+Per ovviare a questi problemi nella \acr{glibc} sono definite anche delle
+versioni rientranti delle precedenti funzioni, al solito queste sono
+caratterizzate dall'avere un suffisso \texttt{\_r}, pertanto avremo le due
+funzioni \funcd{gethostbyname\_r} e \funcd{gethostbyname2\_r} i cui prototipi
+sono:
+
+\begin{funcproto}{
+\fhead{netdb.h}
+\fhead{sys/socket.h}
+\fdecl{int gethostbyname\_r(const char *name, struct hostent *ret, 
+    char *buf, size\_t buflen,\\
+\phantom{int gethostbyname\_r(}struct hostent **result, int *h\_errnop)}
+\fdecl{int gethostbyname2\_r(const char *name, int af,
+         struct hostent *ret, char *buf,\\
+\phantom{int gethostbyname2\_r(}size\_t buflen, struct hostent **result, int *h\_errnop)}
+
+\fdesc{Versioni rientranti delle funzioni \func{gethostbyname} e
+  \func{gethostbyname2}.} 
+}
+
+{Le funzioni ritornano $0$ in caso di successo ed un valore diverso da zero per
+  un errore.}
+\end{funcproto}
+
+Gli argomenti \param{name} (e \param{af} per \func{gethostbyname2\_r}) hanno
+lo stesso significato visto in precedenza. Tutti gli altri argomenti hanno lo
+stesso significato per entrambe le funzioni. Per evitare l'uso di variabili
+globali si dovrà allocare preventivamente una struttura \struct{hostent} in
+cui ricevere il risultato, passandone l'indirizzo alla funzione nell'argomento
+\param{ret}.  Inoltre, dato che \struct{hostent} contiene dei puntatori, dovrà
+essere allocato anche un buffer in cui le funzioni possano scrivere tutti i
+dati del risultato dell'interrogazione da questi puntati; l'indirizzo e la
+lunghezza di questo buffer devono essere indicati con gli argomenti
+\param{buf} e \param{buflen}.
+
+Gli ultimi due argomenti vengono utilizzati per avere indietro i risultati
+come \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 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 valore non nulla e all'indirizzo puntato
+da \param{result} sarà salvato un puntatore nullo, mentre a quello puntato da
+\param{h\_errnop} sarà salvato il valore del codice di errore, dato che per
+essere rientrante la funzione non può la variabile globale \var{h\_errno}. In
+questo caso il codice di errore, oltre ai valori di
+tab.~\ref{tab:h_errno_values}, può avere anche quello di \errcode{ERANGE}
+qualora il buffer allocato su \param{buf} non sia sufficiente a contenere i
+dati, in tal caso si dovrà semplicemente ripetere l'esecuzione della funzione
+con un buffer di dimensione maggiore.
+
+Una delle caratteristiche delle interrogazioni al servizio DNS è che queste
+sono normalmente eseguite con il protocollo UDP, ci sono casi in cui si
+preferisce che vengano usate connessioni permanenti con il protocollo TCP. Per
+ottenere questo sono previste delle funzioni apposite (si potrebbero impostare
+direttamente le opzioni di \var{\_\_res.options}, ma queste funzioni
+permettono di semplificare la procedura); la prime sono \funcd{sethostent} e
+\func{endhostent}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{netdb.h}
+\fdecl{void sethostent(int stayopen)}
+\fdesc{Richiede l'uso di connessioni TCP per le interrogazioni ad un server DNS.} 
+\fdecl{void endhostent(void)}
+\fdesc{Disattiva l'uso di connessioni TCP per le interrogazioni ad un server DNS.} 
+}
+
+{Le funzioni non restituiscono nulla, e non danno errori.}
+\end{funcproto}
+
+La funzione \func{sethostent} permette di richiedere l'uso di connessioni TCP
+per la richiesta dei dati, e che queste restino aperte per successive
+richieste; il valore dell'argomento \param{stayopen} indica se attivare questa
+funzionalità, un valore diverso da zero, che indica una condizione vera in C,
+attiva la funzionalità.  Per disattivare l'uso delle connessioni TCP si può
+invece usare \func{endhostent}, e come si vede la funzione è estremamente
+semplice, non richiedendo nessun argomento.
+
+Infine si può richiedere la risoluzione inversa di un indirizzo IP od IPv6,
+per ottenerne il nome a dominio ad esso associato, per fare questo si può
+usare la funzione \funcd{gethostbyaddr}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{netdb.h}
+\fhead{sys/socket.h} 
+\fdecl{struct hostent *gethostbyaddr(const char *addr, int len, int type)}
+\fdesc{Richiede la risoluzione inversa di un indirizzo IP.} 
+}
+
+{La funzione ritorna l'indirizzo ad una struttura \struct{hostent} in caso di
+  successo e \val{NULL} per un errore.}
+\end{funcproto}
+
+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 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}.
+
+La funzione restituisce, in caso di successo, un puntatore ad una struttura
+\struct{hostent}, solo che in questo caso la ricerca viene eseguita
+richiedendo al DNS un record di tipo \texttt{PTR} corrispondente all'indirizzo
+specificato. In caso di errore al solito viene usata la variabile
+\var{h\_errno} per restituire un opportuno codice. In questo caso l'unico
+campo del risultato che interessa è \var{h\_name} che conterrà il nome a
+dominio, la funzione comunque inizializza anche il primo campo della lista
+\var{h\_addr\_list} col valore dell'indirizzo passato come argomento.
+
+Dato che \func{gethostbyaddr} usa un buffer statico, anche di questa funzione
+esiste una versione rientrante \funcd{gethostbyaddr\_r} fornita come
+estensione dalla \acr{glibc}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{netdb.h}
+\fhead{sys/socket.h} 
+\fdecl{struct hostent *gethostbyaddr\_r(const void *addr, socklen\_t len, int type,\\
+\phantom{struct hostent *gethostbyaddr\_r(}struct hostent *ret, char *buf, size\_t buflen,\\
+\phantom{struct hostent *gethostbyaddr\_r(}struct hostent **result, int *h\_errnop);}
+\fdesc{Richiede la risoluzione inversa di un indirizzo IP.} 
+}
+
+{La funzione ritorna $0$ in caso di successo e un valore non nullo per un errore.}
+\end{funcproto}
+
+La funzione prende per gli argomenti \param{addr}, \param{len} e \param{type}
+gli stessi valori di \func{gethostbyaddr} con lo stesso significato, gli
+argomenti successivi vengono utilizzati per restituire i dati, sono identici a
+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
+\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 la \acr{glibc} fornisce 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 nella \acr{glibc} 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:
+
+\begin{funcproto}{
+\fhead{netdb.h}
+\fhead{sys/types.h}
+\fhead{sys/socket.h}
+\fdecl{struct hostent *getipnodebyname(const char *name, int af, int
+    flags, int *error\_num)} 
+\fdesc{Richiede la risoluzione di un nome a dominio.} 
+\fdecl{struct hostent *getipnodebyaddr(const void *addr, size\_t len,
+    int af, int *error\_num)}
+\fdesc{Richiede la risoluzione inversa di un indirizzo IP.} 
+}
+
+{Le funzioni ritornano l'indirizzo ad una struttura \struct{hostent} in caso
+  di successo e \val{NULL} per un errore.}
+\end{funcproto}
+
+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
+(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
+maschera binaria, che permette di specificarne il comportamento nella
+risoluzione dei diversi tipi di indirizzi (IPv4 e IPv6); ciascun bit
+dell'argomento esprime una diversa opzione, e queste possono essere specificate
+con un OR aritmetico delle costanti riportate in
+tab.~\ref{tab:sock_getipnodebyname_flags}.
+
+\begin{table}[!htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|p{8cm}|}
+    \hline
+    \textbf{Costante} & \textbf{Significato} \\
+    \hline
+    \hline
+    \constd{AI\_V4MAPPED}  & Usato con \const{AF\_INET6} per richiedere una
+                             ricerca su un indirizzo IPv4 invece che IPv6; gli
+                             eventuali risultati saranno rimappati su indirizzi 
+                             IPv6.\\
+    \constd{AI\_ALL}       & Usato con \const{AI\_V4MAPPED}; richiede sia
+                             indirizzi IPv4 che IPv6, e gli indirizzi IPv4
+                             saranno rimappati in IPv6.\\
+    \constd{AI\_ADDRCONFIG}& Richiede che una richiesta IPv4 o IPv6 venga
+                             eseguita solo se almeno una interfaccia del
+                             sistema è associata ad un indirizzo di tale tipo.\\
+    \constd{AI\_DEFAULT}   & Il valore di default, è equivalente alla
+                             combinazione di \const{AI\_ADDRCONFIG} e di
+                             \const{AI\_V4MAPPED}.\\  
+    \hline
+  \end{tabular}
+  \caption{Valori possibili per i bit dell'argomento \param{flags} della
+    funzione \func{getipnodebyname}.}
+  \label{tab:sock_getipnodebyname_flags}
+\end{table}
+
+Entrambe le funzioni restituiscono un puntatore ad una struttura \var{hostent}
+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 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}
+\fhead{sys/socket.h}
+\fdecl{void freehostent(struct hostent *ip)}
+\fdesc{Disalloca una struttura \var{hostent}.} 
+}
 
-Il terzo campo, \var{h\_addrtype}, indica il tipo di indirizzo che è stato
-restituito, e può essere solo \const{AF\_INET} o \const{AF\_INET6}, mentre il
-quarto campo, e \var{h\_length} indica la lunghezza dell'indirizzo stesso in
-byte. Infine il campo \var{h\_addr\_list} è il puntatore ad un vettore di
-puntatori ai singoli indirizzi; il vettore è terminato da un puntatore nullo.
-Inoltre, come illustrato in fig.~\ref{fig:sock_hostent_struct}, viene definito
-per compatibilità il campo \var{h\_addr} corrispondente al puntatore al primo
-indirizzo della lista.
+{La funzione non ritorna nulla, e non da errori.}
+\end{funcproto}
 
-In sostanza 
+La funzione permette di disallocare una struttura \var{hostent}
+precedentemente allocata in una chiamata di \func{getipnodebyname} o
+\func{getipnodebyaddr}, e prende come argomento l'indirizzo restituito da una
+di queste funzioni.
 
+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{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
+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 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.
 
+\begin{table}[!htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|l|l|l|l|}
+    \hline
+    \textbf{Informazione}&\textbf{File}&\textbf{Struttura}&
+    \multicolumn{2}{|c|}{\textbf{Funzioni}}\\
+    \hline
+    \hline
+    indirizzo &\conffile{/etc/hosts}&\struct{hostent}&\func{gethostbyname}&
+               \func{gethostbyaddr}\\ 
+    servizio  &\conffile{/etc/services}&\struct{servent}&\func{getservbyname}&
+               \func{getservbyport}\\ 
+    rete      &\conffile{/etc/networks}&\struct{netent}&\funcm{getnetbyname}&
+               \funcm{getnetbyaddr}\\ 
+    protocollo&\conffile{/etc/protocols}&\struct{protoent}&
+               \funcm{getprotobyname}&\funcm{getprotobyaddr}\\ 
+    \hline
+  \end{tabular}
+  \caption{Funzioni di risoluzione dei nomi per i vari servizi del
+    \textit{Name Service Switch} riguardanti la rete.}
+  \label{tab:name_resolution_functions}
+\end{table}
+
+Delle funzioni di tab.~\ref{tab:name_resolution_functions} abbiamo trattato
+finora soltanto quelle relative alla risoluzione dei nomi, dato che sono le
+più usate, e prevedono praticamente da sempre la necessità di rivolgersi ad
+una entità esterna; per le altre invece, estensioni fornite dal \textit{Name
+  Service Switch} a parte, si fa sempre riferimento ai dati mantenuti nei
+rispettivi file.
+
+Dopo la risoluzione dei nomi a dominio una delle ricerche più comuni è quella
+sui nomi dei servizi di rete più comuni (cioè \texttt{http}, \texttt{smtp},
+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{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 (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},
+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 \conffile{/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]{0.80\textwidth}
+    \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 utilizzano una loro struttura dedicata del tutto analoga alle
+precedenti: 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{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}.} 
+}
+
+{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
+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
+\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. 
+
+\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  &\func{setservent} &\func{getservent} &\func{endservent}\\ 
+    rete      &\funcm{setnetent}  &\funcm{getnetent}  &\funcm{endnetent}\\ 
+    protocollo&\funcm{setprotoent}&\funcm{getprotoent}&\funcm{endprotoent}\\ 
+    \hline
+  \end{tabular}
+  \caption{Funzioni lettura sequenziale dei dati del
+    \textit{Name Service Switch}.} 
+  \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}
+
+Quelle illustrate nella sezione precedente sono le funzioni classiche per la
+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, 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
+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
+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 è:
+
+
+\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.} 
+}
+
+{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,
+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 \val{NULL}, nel qual caso la risoluzione verrà effettuata soltanto
+sulla base del valore dell'altro.
+
+Il terzo argomento, \param{hints}, deve essere invece un puntatore ad una
+struttura \struct{addrinfo} usata per dare dei \textsl{suggerimenti} al
+procedimento di risoluzione riguardo al protocollo o del tipo di socket che si
+intenderà utilizzare; \func{getaddrinfo} infatti permette di effettuare
+ricerche generiche sugli indirizzi, usando sia IPv4 che IPv6, e richiedere
+risoluzioni sui nomi dei servizi indipendentemente dal protocollo (ad esempio
+TCP o UDP) che questi possono utilizzare.
+
+Come ultimo argomento in \param{res} deve essere passato un puntatore ad una
+variabile (di tipo puntatore ad una struttura \struct{addrinfo}) che verrà
+utilizzata dalla funzione per riportare (come \textit{value result argument})
+i propri risultati. La funzione infatti è rientrante, ed alloca autonomamente
+tutta la memoria necessaria in cui verranno riportati i risultati della
+risoluzione.  La funzione scriverà all'indirizzo puntato da \param{res} il
+puntatore iniziale ad una \textit{linked list} di strutture di tipo
+\struct{addrinfo} contenenti tutte le informazioni ottenute.
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{0.90\textwidth}
+    \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}
+
+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 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.
+
+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 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
+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{AF\_INET} e \const{AF\_INET6}, mentre
+se non si vuole specificare nessuna famiglia di indirizzi si può usare il
+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,
+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
+\conffile{/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.
+
+\begin{table}[!htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|p{8cm}|}
+    \hline
+    \textbf{Costante} & \textbf{Significato} \\
+    \hline
+    \hline
+    \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
+                              \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}. \\ 
+    \constd{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.\\ 
+    \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}.\\  
+    \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 
+    \struct{addrinfo}.} 
+  \label{tab:ai_flags_values}
+\end{table}
+
+% 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 dalla \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
+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
+    \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\_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
+                            \param{node} e \param{service}. \\
+    \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\_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
+% TODO estensioni GNU, trovarne la documentazione
+%    \constd{EAI\_INPROGRESS}& Richiesta in corso. \\
+%    \constd{EAI\_CANCELED}& La richiesta è stata cancellata.\\
+%    \constd{EAI\_NOTCANCELED}& La richiesta non è stata cancellata. \\
+%    \constd{EAI\_ALLDONE} & Tutte le richieste sono complete. \\
+%    \constd{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, 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 è:
+
+\begin{funcproto}{
+\fhead{netdb.h} 
+\fdecl{const char *gai\_strerror(int errcode)}
+\fdesc{Fornisce il messaggio corrispondente ad un errore di \func{getaddrinfo}.} 
+}
+
+{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, 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}.
+
+\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 \textit{resolver} basato questa funzione, il
+cui corpo principale è riportato in fig.~\ref{fig:mygetaddr_example}. Il
+codice completo del programma, compresa la gestione delle opzioni in cui è
+gestita l'eventuale inizializzazione dell'argomento \var{hints} per
+restringere le ricerche su protocolli, tipi di socket o famiglie di indirizzi,
+è disponibile nel file \texttt{mygetaddr.c} dei sorgenti allegati alla guida.
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{\codesamplewidth}
+    \includecodesample{listati/mygetaddr.c}
+  \end{minipage}
+  \normalsize
+  \caption{Esempio di codice per la risoluzione di un indirizzo.}
+  \label{fig:mygetaddr_example}
+\end{figure}
+
+Il corpo principale inizia controllando (\texttt{\small 1--5}) il numero di
+argomenti passati, che devono essere sempre due, e corrispondere
+rispettivamente all'indirizzo ed al nome del servizio da risolvere. A questo
+segue la chiamata (\texttt{\small 7}) alla funzione \func{getaddrinfo}, ed il
+successivo controllo (\texttt{\small 8--11}) del suo corretto funzionamento,
+senza il quale si esce immediatamente stampando il relativo codice di errore.
+
+Se la funzione ha restituito un valore nullo il programma prosegue
+inizializzando (\texttt{\small 12}) il puntatore \var{ptr} che sarà usato nel
+successivo ciclo (\texttt{\small 14--35}) di scansione della lista delle
+strutture \struct{addrinfo} restituite dalla funzione. Prima di eseguire
+questa scansione (\texttt{\small 12}) viene stampato il valore del nome
+canonico che è presente solo nella prima struttura.
+
+La scansione viene ripetuta (\texttt{\small 14}) fintanto che si ha un
+puntatore valido. La selezione principale è fatta sul campo \var{ai\_family},
+che stabilisce a quale famiglia di indirizzi fa riferimento la struttura in
+esame. Le possibilità sono due, un indirizzo IPv4 o IPv6, se nessuna delle due
+si verifica si provvede (\texttt{\small 27--30}) a stampare un messaggio di
+errore ed uscire (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
+  31--34}). Il primo caso esaminato (\texttt{\small 15--21}) è quello degli
+indirizzi IPv4, nel qual caso prima se ne stampa l'identificazione
+(\texttt{\small 16}) poi si provvede a ricavare la struttura degli indirizzi
+(\texttt{\small 17}) indirizzata dal campo \var{ai\_addr}, eseguendo un
+opportuno casting del puntatore per poter estrarre da questa la porta
+(\texttt{\small 18}) e poi l'indirizzo (\texttt{\small 19}) che verrà
+convertito con una chiamata ad \func{inet\_ntop}.
+
+La stessa operazione (\texttt{\small 21--27}) viene ripetuta per gli indirizzi
+IPv6, usando la rispettiva struttura degli indirizzi. Si noti anche come in
+entrambi i casi per la chiamata a \func{inet\_ntop} si sia dovuto passare il
+puntatore al campo contenente l'indirizzo IP nella struttura puntata dal campo
+\var{ai\_addr}.\footnote{il meccanismo è complesso a causa del fatto che al
+  contrario di IPv4, in cui l'indirizzo IP può essere espresso con un semplice
+  numero intero, in IPv6 questo deve essere necessariamente fornito come
+  struttura, e pertanto anche se nella struttura puntata da \var{ai\_addr}
+  sono presenti direttamente i valori finali, per l'uso con \func{inet\_ntop}
+  occorre comunque passare un puntatore agli stessi (ed il costrutto
+  \code{\&addr6->sin6\_addr} è corretto in quanto l'operatore \texttt{->} ha
+  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
+passo (\texttt{\small 34}) è di estrarre da \var{ai\_next} l'indirizzo della
+eventuale successiva struttura presente nella lista e ripetere il ciclo, fin
+tanto che, completata la scansione, questo avrà un valore nullo e si potrà
+terminare (\texttt{\small 36}) il programma.
+
+Si tenga presente che \func{getaddrinfo} non garantisce nessun particolare
+ordinamento della lista delle strutture \struct{addrinfo} restituite, anche se
+usualmente i vari indirizzi IP (se ne è presente più di uno) sono forniti
+nello stesso ordine in cui vengono inviati dal server DNS. In particolare
+nulla garantisce che vengano forniti prima i dati relativi ai servizi di un
+determinato protocollo o tipo di socket, se ne sono presenti di diversi.  Se
+allora utilizziamo il nostro programma potremo verificare il risultato:
+\begin{Console}
+[piccardi@gont sources]$ \textbf{./mygetaddr -c  gapil.truelite.it echo}
+Canonical name sources2.truelite.it
+IPv4 address:
+        Indirizzo 62.48.34.25
+        Protocollo 6
+        Porta 7
+IPv4 address:
+        Indirizzo 62.48.34.25
+        Protocollo 17
+        Porta 7
+\end{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{funcproto}{
+\fhead{netdb.h}
+\fdecl{void freeaddrinfo(struct addrinfo *res)}
+\fdesc{Libera la memoria allocata da una precedente chiamata a \func{getaddrinfo}.} 
+}
+
+{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} 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
+avere cura di eseguire una \textit{deep copy} in cui si copiano anche tutti i
+dati presenti agli indirizzi contenuti nella struttura \struct{addrinfo},
+perché una volta disallocati i dati con \func{freeaddrinfo} questi non
+sarebbero più disponibili.
+
+Anche la nuova interfaccia definita da POSIX prevede una nuova funzione per
+eseguire la risoluzione inversa e determinare nomi di servizi e di dominio
+dati i rispettivi valori numerici. La funzione che sostituisce le varie
+\func{gethostbyname}, \func{getipnodebyname} e \func{getservbyname} è
+\funcd{getnameinfo}, ed il suo prototipo è:
+
+\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.} 
+}
+
+{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
+protocollo; il suo primo argomento \param{sa} infatti è il puntatore ad una
+struttura degli indirizzi generica, che può contenere sia indirizzi IPv4 che
+IPv6, la cui dimensione deve comunque essere specificata con l'argomento
+\param{salen}. 
+
+I risultati della funzione saranno restituiti nelle due stringhe puntate da
+\param{host} e \param{serv}, che dovranno essere state precedentemente
+allocate per una lunghezza massima che deve essere specificata con gli altri
+due argomenti \param{hostlen} e \param{servlen}. 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}, nella seconda parte della tabella si sono
+aggiunti i valori introdotto con la \acr{glibc} 2.3.4 per gestire la
+internazionalizzione dei nomi a dominio.
+
+\begin{table}[!htb]
+  \centering
+  \footnotesize
+  \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\_NUMERICSERV}& Richiede che il servizio venga restituito in
+                              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  
+    funzione \func{getnameinfo}.} 
+  \label{tab:getnameinfo_flags}
+\end{table}
+
+La funzione ritorna zero in caso di successo, e scrive i propri risultati agli
+indirizzi indicati dagli argomenti \param{host} e \param{serv} come stringhe
+terminate dal carattere NUL, a meno che queste non debbano essere troncate
+qualora la loro dimensione ecceda quelle specificate dagli argomenti
+\param{hostlen} e \param{servlen}. Sono comunque definite le due costanti
+\constd{NI\_MAXHOST} e \constd{NI\_MAXSERV}\footnote{in Linux le due costanti
+  sono definite in \headfile{netdb.h} ed hanno rispettivamente il valore 1024
+  e 12.}  che possono essere utilizzate come limiti massimi.  In caso di
+errore viene restituito invece un codice che assume gli stessi valori
+illustrati in tab.~\ref{tab:addrinfo_error_code}.
+
+A questo punto possiamo fornire degli esempi di utilizzo della nuova
+interfaccia, adottandola per le precedenti implementazioni del client e del
+server per il servizio \textit{echo}; dato che l'uso delle funzioni appena
+illustrate (in particolare di \func{getaddrinfo}) è piuttosto complesso,
+essendo necessaria anche una impostazione diretta dei campi dell'argomento
+\param{hints}, provvederemo una interfaccia semplificata per i due casi visti
+finora, quello in cui si specifica nel client un indirizzo remoto per la
+connessione al server, e quello in cui si specifica nel server un indirizzo
+locale su cui porsi in ascolto.
+
+La prima funzione della nostra interfaccia semplificata è \texttt{sockconn}
+che permette di ottenere un socket, connesso all'indirizzo ed al servizio
+specificati. Il corpo della funzione è riportato in
+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}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{\codesamplewidth}
+    \includecodesample{listati/sockconn.c}
+  \end{minipage}
+  \normalsize
+  \caption{Il codice della funzione \texttt{sockconn}.}
+  \label{fig:sockconn_code}
+\end{figure}
+
+La funzione prende quattro argomenti, i primi due sono le stringhe che
+indicano il nome della macchina a cui collegarsi ed il relativo servizio su
+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 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.
+
+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
+entrambi i casi (\texttt{\small 32} e (\texttt{\small 36}) la chiusura del
+socket precedentemente aperto, che non è più utilizzabile.
+
+Se la connessione ha avuto successo invece si termina (\texttt{\small 39})
+direttamente il ciclo, e prima di ritornare (\texttt{\small 31}) il valore del
+file descriptor del socket si provvede (\texttt{\small 30}) a liberare le
+strutture \struct{addrinfo} allocate da \func{getaddrinfo} utilizzando il
+valore del relativo puntatore precedentemente (\texttt{\small 17}) salvato.
+Si noti come per la funzione sia del tutto irrilevante se la struttura
+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}.
+
+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})
+avremo una semplificazione per cui il corpo principale del nostro client
+diventerà quello illustrato in fig.~\ref{fig:TCP_echo_fifth}, in cui le
+chiamate a \func{socket}, \func{inet\_pton} e \func{connect} sono sostituite
+da una singola chiamata a \texttt{sockconn}. Inoltre il nuovo client (il cui
+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}[!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}
+  \end{minipage}
+  \normalsize
+  \caption{Il codice della funzione \texttt{sockbind}.}
+  \label{fig:sockbind_code}
+\end{figure}
+
+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
+sez.~\ref{sec:TCP_func_bind}, relativamente al significato della scelta di un
+indirizzo specifico come argomento di \func{bind}, che consente di porre il
+server in ascolto su uno solo dei possibili diversi indirizzi presenti su di
+una macchina.  Se non si vuole che la funzione esegua \func{bind} su un
+indirizzo specifico, ma utilizzi l'indirizzo generico, occorrerà avere cura di
+passare un valore \val{NULL} come valore per l'argomento \var{host}; l'uso
+del valore \const{AI\_PASSIVE} serve ad ottenere il valore generico nella
+rispettiva struttura degli indirizzi.
+
+Come già detto la funzione è analoga a \texttt{sockconn} ed inizia azzerando
+ed inizializzando (\texttt{\small 6--11}) opportunamente la struttura
+\var{hint} con i valori ricevuti come argomenti, soltanto che in questo caso
+si è usata (\texttt{\small 8}) una impostazione specifica dei flag di
+\var{hint} usando \const{AI\_PASSIVE} per indicare che il socket sarà usato
+per una apertura passiva. Per il resto la chiamata (\texttt{\small 12--18}) a
+\func{getaddrinfo} e ed il ciclo principale (\texttt{\small 20--42}) sono
+identici, solo che si è sostituita (\texttt{\small 31}) la chiamata a
+\func{connect} con una chiamata a \func{bind}. Anche la conclusione
+(\texttt{\small 43--44}) della funzione è identica.
+
+Si noti come anche in questo caso si siano inserite le stampe degli errori
+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
+  \begin{minipage}[c]{\codesamplewidth}
+    \includecodesample{listati/TCP_echod_third.c}
+  \end{minipage}
+  \normalsize
+  \caption{Nuovo codice per l'apertura passiva del server \textit{echo}.}
+  \label{fig:TCP_echod_third}
+\end{figure}
+
+Con l'uso di questa funzione si può modificare anche il codice del nostro
+server \textit{echo}, che rispetto a quanto illustrato nella versione iniziale
+di fig.~\ref{fig:TCP_echo_server_first_code} viene modificato nella forma
+riportata in fig.~\ref{fig:TCP_echod_third}. In questo caso il socket su cui
+porsi in ascolto viene ottenuto (\texttt{\small 15--18}) da \texttt{sockbind}
+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:TCP_sock_options}
+\label{sec:sock_options}
 
-Finora abbiamo trattato i socket nel loro comportamento più comune, è però
-possibile attivare alcune modalità diverse di funzionamento degli stessi
+Benché dal punto di vista del loro uso come canali di trasmissione di dati i
+socket vengano trattati allo stesso modo dei file, 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 controllare la moltitudine di caratteristiche
+specifiche che li contraddistinguono, considerato tra l'altro che queste
+possono essere completamente diverse fra loro a seconda del tipo di socket e
+della relativa forma di comunicazione sottostante.
 
-Dato che la maggior parte delle opzioni dei socket sono relative ai socket
-TCP, ed hanno poi significato analogo quando usate con altri socket, abbiamo
-preferito trattare l'argomento in generale in questa sezione piuttosto che nel
-capitolo dedicato alla trattazione generica dei socket.
+In questa sezione vedremo allora quali sono le funzioni dedicate alla gestione
+delle caratteristiche specifiche dei vari tipi di socket, che vengono
+raggruppate sotto il nome generico di ``\textit{socket options}'', ma
+soprattutto analizzaremo quali sono queste opzioni e quali caretteristiche e
+comportamenti dei socket permettono di controllare.
 
-\section{Altre funzioni di controllo}
-\label{sec:TCP_sock_ctrl}
 
+\subsection{Le funzioni di gestione delle opzioni dei socket}
+\label{sec:sock_setsockopt}
 
+La modalità principale con cui si possono gestire le caratteristiche dei
+socket (ne vedremo delle ulteriori nelle prossime sezioni) è quella che passa
+attraverso l'uso di due funzioni di sistema 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{funcproto}{
+\fhead{sys/socket.h}
+\fhead{sys/types.h}
+\fdecl{int setsockopt(int sock, int level, int optname, const void
+    *optval, socklen\_t optlen)}
+\fdesc{Imposta le opzioni di un socket.} 
+}
 
+{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.
+  \item[\errcode{EINVAL}] il valore di \param{optlen} non è valido.
+  \item[\errcode{ENOPROTOOPT}] l'opzione scelta non esiste per il livello
+    indicato. 
+  \item[\errcode{ENOTSOCK}] il file descriptor \param{sock} non corrisponde ad
+    un socket.
+  \end{errlist}
+}
+\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
+argomenti successivi, \param{level} e \param{optname}.  Come abbiamo visto in
+sez.~\ref{sec:net_protocols} i protocolli di rete sono strutturati su vari
+livelli, ed l'interfaccia dei socket può usarne più di uno. Si avranno allora
+funzionalità e caratteristiche diverse per ciascun protocollo usato da un
+socket, e quindi saranno anche diverse le opzioni che si potranno impostare
+per ciascun socket, a seconda del \textsl{livello} (trasporto, rete, ecc.) su
+cui si vuole andare ad operare.
+
+Il valore di \param{level} seleziona allora il protocollo su cui vuole
+intervenire, mentre \param{optname} permette di scegliere su quale delle
+opzioni che sono definite per quel protocollo si vuole operare. In sostanza la
+selezione di una specifica opzione viene fatta attraverso una coppia di valori
+\param{level} e \param{optname} e chiaramente la funzione avrà successo
+soltanto se il protocollo in questione prevede quella opzione ed è utilizzato
+dal socket.  Infine \param{level} prevede anche il valore speciale
+\const{SOL\_SOCKET} usato per le opzioni generiche che sono disponibili per
+qualunque tipo di socket.
+
+\begin{table}[!htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|l|}
+    \hline
+    \textbf{Livello} & \textbf{Significato} \\
+    \hline
+    \hline
+    \constd{SOL\_SOCKET}& Opzioni generiche dei socket.\\
+    \constd{SOL\_IP}    & Opzioni specifiche per i socket che usano IPv4.\\
+    \constd{SOL\_TCP}   & Opzioni per i socket che usano TCP.\\
+    \constd{SOL\_IPV6}  & Opzioni specifiche per i socket che usano IPv6.\\
+    \constd{SOL\_ICMPV6}& Opzioni specifiche per i socket che usano ICMPv6.\\
+    \hline
+  \end{tabular}
+  \caption{Possibili valori dell'argomento \param{level} delle 
+    funzioni \func{setsockopt} e \func{getsockopt}.} 
+  \label{tab:sock_option_levels}
+\end{table}
+
+I valori usati per \param{level}, corrispondenti ad un dato protocollo usato
+da un socket, sono quelli corrispondenti al valore numerico che identifica il
+suddetto protocollo in \conffile{/etc/protocols}; dato che la leggibilità di un
+programma non trarrebbe certo beneficio dall'uso diretto dei valori numerici,
+più comunemente si indica il protocollo tramite le apposite costanti
+\texttt{SOL\_*} riportate in tab.~\ref{tab:sock_option_levels}, dove si sono
+riassunti i valori che possono essere usati per l'argomento
+\param{level}. 
+
+La notazione in questo caso è, purtroppo, abbastanza confusa: infatti in Linux
+il valore si può impostare sia usando le costanti \texttt{SOL\_*}, che le
+analoghe \texttt{IPPROTO\_*} (citate anche da Stevens in \cite{UNP1});
+entrambe hanno gli stessi valori che sono equivalenti ai numeri di protocollo
+di \conffile{/etc/protocols}, con una eccezione specifica, che è quella del
+protocollo ICMP, per la quale non esiste una costante, il che è comprensibile
+dato che il suo valore, 1, è quello che viene assegnato a \const{SOL\_SOCKET}.
+
+Il quarto argomento, \param{optval} è un puntatore ad una zona di memoria che
+contiene i dati che specificano il valore dell'opzione che si vuole passare al
+socket, mentre l'ultimo argomento \param{optlen},\footnote{questo argomento è
+  in realtà sempre di tipo \ctyp{int}, come era nelle \acr{libc4} e
+  \acr{libc5}; l'uso di \type{socklen\_t} è stato introdotto da POSIX (valgono
+  le stesse considerazioni per l'uso di questo tipo di dato fatte in
+  sez.~\ref{sec:TCP_func_accept}) ed adottato dalla \acr{glibc}.} è la
+dimensione in byte dei dati presenti all'indirizzo indicato da \param{optval}.
+Dato che il tipo di dati varia a seconda dell'opzione scelta, occorrerà
+individuare qual è quello che deve essere usato, ed utilizzare le opportune
+variabili.
+
+La gran parte delle opzioni utilizzano per \param{optval} un valore intero, se
+poi l'opzione esprime una condizione logica, il valore è sempre un intero, ma
+si dovrà usare un valore non nullo per abilitarla ed un valore nullo per
+disabilitarla.  Se invece l'opzione non prevede di dover ricevere nessun tipo
+di valore si deve impostare \param{optval} a \val{NULL}. Un piccolo numero
+di opzioni però usano dei tipi di dati peculiari, è questo il motivo per cui
+\param{optval} è stato definito come puntatore generico.
+
+La seconda funzione usata per controllare le proprietà dei socket è
+\funcd{getsockopt}, che serve a leggere i valori delle opzioni dei socket ed a
+farsi restituire i dati relativi al loro funzionamento; il suo prototipo è:
+
+
+\begin{funcproto}{
+\fhead{sys/socket.h}
+\fhead{sys/types.h}
+\fdecl{int getsockopt(int s, int level, int optname, void *optval,
+    socklen\_t *optlen)}
+\fdesc{Legge le opzioni di un socket.} 
+}
+
+{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} o quello di
+    \param{optlen} non è valido.
+  \item[\errcode{ENOPROTOOPT}] l'opzione scelta non esiste per il livello
+    indicato. 
+  \item[\errcode{ENOTSOCK}] il file descriptor \param{sock} non corrisponde ad
+    un socket.
+  \end{errlist}
+}
+\end{funcproto}
+
+I primi tre argomenti sono identici ed hanno lo stesso significato di quelli
+di \func{setsockopt}, anche se non è detto che tutte le opzioni siano definite
+per entrambe le funzioni. In questo caso \param{optval} viene usato per
+ricevere le informazioni ed indica l'indirizzo a cui andranno scritti i dati
+letti dal socket, infine \param{optlen} diventa un puntatore ad una variabile
+che viene usata come \textit{value result argument} per indicare, prima della
+chiamata della funzione, la lunghezza del buffer allocato per \param{optval} e
+per ricevere indietro, dopo la chiamata della funzione, la dimensione
+effettiva dei dati scritti su di esso.  Se la dimensione del buffer allocato
+per \param{optval} non è sufficiente si avrà un errore.
+
+
+
+\subsection{Le opzioni generiche}
+\label{sec:sock_generic_options}
+
+Come accennato esiste un insieme generico di opzioni dei socket che possono
+applicarsi a qualunque tipo di socket, indipendentemente da quale protocollo
+venga poi utilizzato. Una descrizione di queste opzioni è generalmente
+disponibile nella settima sezione delle pagine di manuale; nel caso specifico
+la si può consultare con \texttt{man 7 socket}. Se si vuole operare su queste
+opzioni generiche il livello da utilizzare è \const{SOL\_SOCKET}; si è
+riportato un elenco di queste opzioni in tab.~\ref{tab:sock_opt_socklevel}.
+
+
+\begin{table}[!htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|c|c|c|l|l|}
+    \hline
+    \textbf{Opzione}&\texttt{get}&\texttt{set}&\textbf{flag}&\textbf{Tipo}&
+                    \textbf{Descrizione}\\
+    \hline
+    \hline
+    \const{SO\_ACCEPTCONN}&$\bullet$&        &         &\texttt{int}& 
+                          Indica se il socket è in ascolto.\\
+    \const{SO\_ATTACH\_FILTER}&     &$\bullet$&         &\texttt{sock\_fprog}& 
+                          Aggancia un filtro BPF al socket.\\
+    \const{SO\_BINDTODEVICE}&$\bullet$&$\bullet$&         &\texttt{char *}& 
+                          Lega il socket ad un dispositivo.\\
+    \const{SO\_BROADCAST}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
+                          Attiva o disattiva il \textit{broadcast}.\\ 
+    \const{SO\_BSDCOMPAT}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
+                          Abilita la compatibilità con BSD.\\
+    \const{SO\_BUSY\_POLL}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
+                          Attiva il ``\textit{busy poll}'' sul socket.\\
+    \const{SO\_DEBUG}    &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
+                          Abilita il debugging sul socket.\\
+    \const{SO\_DETACH\_FILTER}&    &$\bullet$&$\bullet$&\texttt{int}& 
+                          Rimuove il filtro BPF agganciato al socket.\\
+    \const{SO\_DOMAIN}   &$\bullet$&         &         &\texttt{int}& 
+                          Legge il tipo di socket.\\
+    \const{SO\_DONTROUTE}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
+                          Non invia attraverso un gateway.\\
+    \const{SO\_ERROR}    &$\bullet$&         &         &\texttt{int}& 
+                          Riceve e cancella gli errori pendenti.\\
+    \const{SO\_KEEPALIVE}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
+                          Controlla l'attività della connessione.\\
+    \const{SO\_LINGER}   &$\bullet$&$\bullet$&         &\texttt{linger}&
+                          Indugia nella chiusura con dati da spedire.\\
+    \const{SO\_LOCK\_FILTER}&    &$\bullet$&$\bullet$&\texttt{int}& 
+                          Blocca il filtro BPF agganciato al socket.\\
+    \const{SO\_MARK}     &$\bullet$&$\bullet$&         &\texttt{int}&
+                          Imposta un ``\textit{firewall mark}'' sul socket.\\
+    \const{SO\_OOBINLINE}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
+                          Lascia in linea i dati \textit{out-of-band}.\\
+    \const{SO\_PASSCRED} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
+                          Abilita la ricezione di credenziali.\\
+    \const{SO\_PEEK\_OFF} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
+                          Imposta il valore del ``\textit{peek offset}''.\\
+    \const{SO\_PEERCRED} &$\bullet$&         &         &\texttt{ucred}& 
+                          Restituisce le credenziali del processo remoto.\\
+    \const{SO\_PRIORITY} &$\bullet$&$\bullet$&         &\texttt{int}& 
+                          Imposta la priorità del socket.\\
+    \const{SO\_PROTOCOL} &$\bullet$&         &         &\texttt{int}& 
+                          Ottiene il protocollo usato dal socket.\\
+    \const{SO\_RCVBUF}   &$\bullet$&$\bullet$&         &\texttt{int}& 
+                          Imposta dimensione del buffer di ricezione.\\
+    \const{SO\_RCVBUFFORCE}&$\bullet$&$\bullet$&         &\texttt{int}& 
+                          Forza dimensione del buffer di ricezione.\\
+    \const{SO\_RCVLOWAT} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
+                          Basso livello sul buffer di ricezione.\\
+    \const{SO\_RCVTIMEO} &$\bullet$&$\bullet$&         &\texttt{timeval}& 
+                          Timeout in ricezione.\\
+    \const{SO\_REUSEADDR}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
+                          Consente il riutilizzo di un indirizzo locale.\\
+    \const{SO\_REUSEPORT}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
+                          Consente il riutilizzo di una porta.\\
+    \const{SO\_RXQ\_OVFL} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
+                          Richiede messaggio ancillare con pacchetti persi.\\
+    \const{SO\_SNDBUF}   &$\bullet$&$\bullet$&         &\texttt{int}& 
+                          Imposta dimensione del buffer di trasmissione.\\
+    \const{SO\_SNDBUFFORCE}&$\bullet$&$\bullet$&         &\texttt{int}& 
+                          Forza dimensione del buffer di trasmissione.\\
+    \const{SO\_SNDLOWAT} &$\bullet$&$\bullet$&         &\texttt{int}&
+                          Basso livello sul buffer di trasmissione.\\
+    \const{SO\_SNDTIMEO} &$\bullet$&$\bullet$&         &\texttt{timeval}& 
+                          Timeout in trasmissione.\\
+    \const{SO\_TIMESTAMP}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+                          Abilita/disabilita la ricezione dei \textit{timestamp}.\\
+    \const{SO\_TYPE}     &$\bullet$&         &         &\texttt{int}& 
+                          Restituisce il tipo di socket.\\
+   \hline
+  \end{tabular}
+  \caption{Le opzioni disponibili al livello \const{SOL\_SOCKET}.} 
+  \label{tab:sock_opt_socklevel}
+\end{table}
+
+% TODO aggiungere e documentare SO_ATTACH_BPF, introdotta con il kernel 3.19,
+% vedi http://lwn.net/Articles/625224/
+% TODO aggiungere e documentare SO_INCOMING_CPU, introdotta con il kernel 3.19,
+% TODO documentare SO_PEERGROUPS introdotta con il kernel 4.13, citata
+% in https://lwn.net/Articles/727385/
+% TODO documentare SO_ZEROCOPY, vedi https://lwn.net/Articles/726917/ (e il
+% resto pure) introdotta con il kernel 4.14
+
+La tabella elenca le costanti che identificano le singole opzioni da usare
+come valore per \param{optname}; le due colonne seguenti indicano per quali
+delle due funzioni (\func{getsockopt} o \func{setsockopt}) l'opzione è
+disponibile, mentre la colonna successiva indica, quando si ha a che fare con
+un valore di \param{optval} intero, se l'opzione è da considerare un numero o
+un valore logico. Si è inoltre riportato sulla quinta colonna il tipo di dato
+usato per \param{optval} ed una breve descrizione del significato delle
+singole opzioni sulla sesta.
+
+Le descrizioni delle opzioni presenti in tab.~\ref{tab:sock_opt_socklevel}
+sono estremamente sommarie, è perciò necessario fornire un po' più di
+informazioni. Alcune opzioni inoltre hanno una notevole rilevanza nella
+gestione dei socket, e pertanto il loro utilizzo sarà approfondito
+separatamente in sez.~\ref{sec:sock_options_main}. Quello che segue è quindi
+soltanto un elenco più dettagliato della breve descrizione di
+tab.~\ref{tab:sock_opt_socklevel} sul significato delle varie opzioni:
+
+\begin{basedescript}{\desclabelwidth{2.2cm}\desclabelstyle{\nextlinelabel}}
+\item[\constd{SO\_ACCEPTCONN}] questa opzione permette di rilevare se il socket
+  su cui opera è stato posto in modalità di ricezione di eventuali connessioni
+  con una chiamata a \func{listen}. L'opzione può essere usata soltanto con
+  \func{getsockopt} ed utilizza per \param{optval} un intero in cui viene
+  restituito 1 se il socket è in ascolto e 0 altrimenti.
+
+\item[\constd{SO\_ATTACH\_FILTER}] questa opzione permette di agganciare ad un
+  socket un filtro di selezione dei pacchetti con la stessa sintassi del BPF
+  (\textit{Berkley Packet Filter}) di BSD, che consente di selezionare, fra
+  tutti quelli ricevuti, verranno letti. Può essere usata solo con
+  \func{setsockopt} ed utilizza per \param{optval} un puntatore ad una
+  struttura \struct{sock\_fprog} (definita in
+  \headfile{linux/filter.h}). Questa opzione viene usata principalmente con i
+  socket di tipo \const{AF\_PACKET} (torneremo su questo in
+  sez.~\ref{sec:packet_socket}) dalla libreria \texttt{libpcap} per
+  implementare programmi di cattura dei pacchetti, e per questo tipo di
+  applicazione è opportuno usare sempre quest'ultima.\footnote{la trattazione
+    del BPF va al di là dell'argomento di questa sezione per la documentazione
+    si consulti il file \texttt{networking/filter.txt} nella documentazione
+    del kernel.}
+
+\item[\constd{SO\_BINDTODEVICE}] questa opzione permette di \textsl{legare} il
+  socket ad una particolare interfaccia, in modo che esso possa ricevere ed
+  inviare pacchetti solo su quella. L'opzione richiede per \param{optval} il
+  puntatore ad una stringa contenente il nome dell'interfaccia (ad esempio
+  \texttt{eth0}); utilizzando una stringa nulla o un valore nullo per
+  \param{optlen} si può rimuovere un precedente collegamento.
+
+  Il nome della interfaccia deve essere specificato con una stringa terminata
+  da uno zero e di lunghezza massima pari a \constd{IFNAMSIZ}; l'opzione è
+  effettiva solo per alcuni tipi di socket, ed in particolare per quelli della
+  famiglia \const{AF\_INET}; non è invece supportata per i \textit{packet
+    socket} (vedi sez.~\ref{sec:socket_raw}). 
+
+\item[\constd{SO\_BROADCAST}] questa opzione abilita il \textit{broadcast}:
+  quando abilitata i socket di tipo \const{SOCK\_DGRAM} riceveranno i
+  pacchetti inviati all'indirizzo di \textit{broadcast} e potranno scrivere
+  pacchetti su tale indirizzo.  Prende per \param{optval} un intero usato come
+  valore logico. L'opzione non ha effetti su un socket di tipo
+  \const{SOCK\_STREAM}.
+
+\item[\constd{SO\_BSDCOMPAT}] questa opzione abilita la compatibilità con il
+  comportamento di BSD (in particolare ne riproduce alcuni bug).  Attualmente
+  è una opzione usata solo per il protocollo UDP e ne è prevista la rimozione.
+  L'opzione utilizza per \param{optval} un intero usato come valore logico.
+
+  Quando viene abilitata gli errori riportati da messaggi ICMP per un socket
+  UDP non vengono passati al programma in \textit{user space}. Con le versioni
+  2.0.x del kernel erano anche abilitate altre opzioni di compatibilità per i
+  socket raw (modifiche casuali agli header, perdita del flag di
+  \textit{broadcast}) che sono state rimosse con il passaggio al 2.2; è
+  consigliato correggere i programmi piuttosto che usare questa funzione. Dal
+  kernel 2.4 viene ignorata, e dal 2.6 genera un messaggio di log del kernel.
+
+\item[\constd{SO\_BUSY\_POLL}] questa opzione, presente dal kernel 3.11,
+  imposta un tempo approssimato in microsecondi, per cui in caso di ricezione
+  bloccante verrà eseguito un \itindex{busy~poll} ``\textit{busy
+    poll}'',\footnote{con \textit{busy poll} si fa riferimento al
+    \textit{polling} su una risorsa occupata; si continuerà cioè a tentare di
+    leggere anche quando non ci sono dati senza portare il processo stato di
+    \textit{sleep}, in alcuni casi, quando ci si aspetta che i dati arrivino a
+    breve, questa tecnica può dare un miglioramento delle prestazioni.}  da
+  indicare in \param{optval} con un valore intero. Si tratta di una opzione
+  utilizzabile solo con socket che ricevono dati da un dispositivo di rete che
+  la supporti, e che consente di ridurre la latenza per alcune applicazioni,
+  ma che comporta un maggiore utilizzo della CPU (e quindi di energia); per
+  questo il valore può essere aumentato solo da processi con i privilegi di
+  amministratore (in particolare con la \textit{capability}
+  \const{CAP\_NET\_ADMIN}).  Il valore di default viene controllato dal file
+  \sysctlrelfile{net/core}{busy\_read} per le funzioni di lettura mentre il
+  file \sysctlrelfile{net/core}{busy\_poll} controlla il ``\textit{busy
+    poll}'' per \func{select} e \func{poll}.
+
+\item[\constd{SO\_DEBUG}] questa opzione abilita il debugging delle operazioni
+  dei socket; l'opzione utilizza per \param{optval} un intero usato come
+  valore logico, e può essere utilizzata solo da un processo con i privilegi
+  di amministratore (in particolare con la \textit{capability}
+  \const{CAP\_NET\_ADMIN}).  L'opzione necessita inoltre dell'opportuno
+  supporto nel kernel;\footnote{deve cioè essere definita la macro di
+    preprocessore \macrod{SOCK\_DEBUGGING} nel file \file{include/net/sock.h}
+    dei sorgenti del kernel, questo è sempre vero nei kernel delle serie
+    superiori alla 2.3, per i kernel delle serie precedenti invece è
+    necessario aggiungere a mano detta definizione; è inoltre possibile
+    abilitare anche il tracciamento degli stati del TCP definendo la macro
+    \macrod{STATE\_TRACE} in \file{include/net/tcp.h}.}  quando viene
+  abilitata una serie di messaggi con le informazioni di debug vengono inviati
+  direttamente al sistema del kernel log.\footnote{si tenga presente che il
+    comportamento è diverso da quanto avviene con BSD, dove l'opzione opera
+    solo sui socket TCP, causando la scrittura di tutti i pacchetti inviati
+    sulla rete su un buffer circolare che viene letto da un apposito
+    programma, \cmd{trpt}.}
+
+\item[\constd{SO\_DETACH\_FILTER}] consente di distaccare un filtro
+  precedentemente aggiunto ad un socket con l'opzione
+  \const{SO\_ATTACH\_FILTER}, in genere non viene usata direttamente in quanto
+  i filtri BPF vengono automaticamente rimossi alla chiusura del socket, il
+  suo utilizzo è pertanto limitato ai rari casi in cui si vuole rimuovere un
+  precedente filtro per inserirne uno diverso. Come \const{SO\_ATTACH\_FILTER}
+  può essere usato solo \func{setsockopt} e prende per \param{optval} un
+  intero usato come valore logico.
+
+\item[\constd{SO\_DOMAIN}] questa opzione, presente dal kernel 2.6.32, legge
+  il ``\textsl{dominio}'' (la famiglia di indirizzi) del socket.
+. Funziona solo con \func{getsockopt}, ed
+  utilizza per \param{optval} un intero in cui verrà restituito il valore
+  numerico che lo identifica (ad esempio \texttt{AF\_INET}).
+
+\item[\constd{SO\_DONTROUTE}] questa opzione richiede che l'invio dei
+  pacchetti del socket sia eseguito soltanto verso una destinazione
+  direttamente connessa, impedendo l'uso di un \textit{gateway} e saltando
+  ogni processo relativo all'uso della tabella di routing del kernel. Prende
+  per \param{optval} un intero usato come valore logico. È equivalente all'uso
+  del flag \const{MSG\_DONTROUTE} su una \func{send} (vedi
+  sez.~\ref{sec:net_send_recv}).
+
+\item[\constd{SO\_ERROR}] questa opzione riceve un errore presente sul socket;
+  può essere utilizzata soltanto con \func{getsockopt} e prende per
+  \param{optval} un valore intero, nel quale viene restituito il codice di
+  errore, e la condizione di errore sul socket viene cancellata. Viene
+  usualmente utilizzata per ricevere il codice di errore, come accennato in
+  sez.~\ref{sec:TCP_sock_select}, quando si sta osservando il socket con una
+  \func{select} che ritorna a causa dello stesso.
+
+\item[\const{SO\_KEEPALIVE}] questa opzione abilita un meccanismo di verifica
+  della persistenza di una connessione associata al socket; è pertanto
+  effettiva solo sui socket che supportano le connessioni, ed è usata
+  principalmente con il TCP. L'opzione utilizza per \param{optval} un intero
+  usato come valore logico. Maggiori dettagli sul suo funzionamento sono
+  forniti in sez.~\ref{sec:sock_options_main}.
+
+\item[\const{SO\_LINGER}] questa opzione controlla le modalità con cui viene
+  chiuso un socket quando si utilizza un protocollo che supporta le
+  connessioni (è pertanto usata con i socket TCP ed ignorata per UDP) e
+  modifica il comportamento delle funzioni \func{close} e \func{shutdown}.
+  L'opzione richiede che l'argomento \param{optval} sia una struttura di tipo
+  \struct{linger}, definita in \headfile{sys/socket.h} ed illustrata in
+  fig.~\ref{fig:sock_linger_struct}.  Maggiori dettagli sul suo funzionamento
+  sono forniti in sez.~\ref{sec:sock_options_main}.
+
+\item[\constd{SO\_LOCK\_FILTER}] consente di bloccare un filtro
+  precedentemente aggiunto ad un socket con l'opzione
+  \const{SO\_ATTACH\_FILTER}, in modo che non possa essere né rimosso né
+  modificato, questo consente di impostare un filtro su un socket, bloccarlo e
+  poi cedere i privilegi con la sicurezza che il filtro permarrà fino alla
+  chiusura del socket. Come \const{SO\_ATTACH\_FILTER} può essere usato solo
+  \func{setsockopt} e prende per \param{optval} un intero usato come valore
+  logico.
+
+\item[\constd{SO\_MARK}] questa opzione, presente dal kernel 2.6.25, imposta
+  un valore di marcatura sui pacchetti del socket. Questa è una funzionalità
+  specifica di Linux, ottenibile anche con l'uso del target \texttt{MARK}
+  del comando \texttt{iptables} (l'argomento è trattato in sez.~3.3.5 di
+  \cite{SGL}). Il valore di marcatura viene mantenuto all'interno dello stack
+  di rete del kernel e può essere usato sia dal \itindex{netfilter}
+  \textit{netfilter}\footnote{il \textit{netfilter} è l'infrastruttura usata
+    per il filtraggio dei pacchetti del kernel, per maggiori dettagli si
+    consulti il cap.~2 di \cite{FwGL}.} di Linux che per impostare politiche
+  di routing avanzato. Il valore deve essere specificato in \param{optval}
+  come un intero. L'opzione richiede i privilegi di amministratore con la
+  \textit{capability} \const{CAP\_NET\_ADMIN}.
+
+\item[\constd{SO\_OOBINLINE}] se questa opzione viene abilitata i dati
+  \textit{out-of-band} vengono inviati direttamente nel flusso di dati del
+  socket (e sono quindi letti con una normale \func{read}) invece che restare
+  disponibili solo per l'accesso con l'uso del flag \const{MSG\_OOB} di
+  \func{recvmsg}. L'argomento è trattato in dettaglio in
+  sez.~\ref{sec:TCP_urgent_data}. L'opzione funziona soltanto con socket che
+  supportino i dati \textit{out-of-band} (non ha senso per socket UDP ad
+  esempio), ed utilizza per \param{optval} un intero usato come valore logico.
+
+\item[\constd{SO\_PASSCRED}] questa opzione abilita sui socket unix-domain
+  (vedi sez.~\ref{sec:unix_socket}) la ricezione dei messaggi di controllo di
+  tipo \const{SCM\_CREDENTIALS}. Prende come \param{optval} un intero usato
+  come valore logico.
+
+\item[\constd{SO\_PEEK\_OFF}] questa opzione, disponibile a partire dal kernel
+  3.4, imposta un ``\textit{peek offset}'' sul socket (attualmente disponibile
+  solo per i socket unix-domain (vedi sez.~\ref{sec:unix_socket}). La funzione
+  serve come ausilio per l'uso del flag \const{MSG\_PEEK} di \func{recv} che
+  consente di ``\textsl{sbirciare}'' nei dati di un socket, cioè di leggerli
+  senza rimuoverli dalla coda in cui sono mantenuti, così che vengano
+  restituiti anche da una successiva lettura ordinaria.
+  Un valore negativo (il default è $-1$) riporta alla situazione ordinaria in
+  cui si ``\textsl{sbircia}'' a partire dalla testa della coda, un valore
+  positivo consente di leggere a partire dalla posizione indicata nella coda e
+  tutte le volte che si sbirciano dei dati il valore dell'offset viene
+  automaticamente aumentato della quantità di dati sbirciati, in modo che si
+  possa proseguire da dove si era arrivati. Il valore deve essere specificato
+  in \param{optval} come intero.
+
+\item[\constd{SO\_PEERCRED}] questa opzione restituisce le credenziali del
+  processo remoto connesso al socket; l'opzione è disponibile solo per socket
+  unix-domain di tipo \textit{stream} e anche per quelli di tipo
+  \textit{datagram} quando se ne crea una coppia con \func{socketpair}, e può
+  essere usata solo con \func{getsockopt}.  Utilizza per
+  \param{optval} una apposita struttura \struct{ucred} (vedi
+  sez.~\ref{sec:unix_socket}). 
+
+\item[\constd{SO\_PRIORITY}] questa opzione permette di impostare le priorità
+  per tutti i pacchetti che sono inviati sul socket, prende per \param{optval}
+  un valore intero. Con questa opzione il kernel usa il valore per ordinare le
+  priorità sulle code di rete,\footnote{questo richiede che sia abilitato il
+    sistema di \textit{Quality of Service} disponibile con le opzioni di
+    routing avanzato.} i pacchetti con priorità più alta vengono processati
+  per primi, in modalità che dipendono dalla disciplina di gestione della
+  coda. Nel caso di protocollo IP questa opzione permette anche di impostare i
+  valori del campo \textit{type of service} (noto come TOS, vedi
+  sez.~\ref{sec:IP_header}) per i pacchetti uscenti. Per impostare una
+  priorità al di fuori dell'intervallo di valori fra 0 e 6 sono richiesti i
+  privilegi di amministratore con la \textit{capability}
+  \const{CAP\_NET\_ADMIN}.
+
+\item[\constd{SO\_PROTOCOL}] questa opzione, presente dal kernel 2.6.32, legge
+  il protocollo usato dal socket. Funziona solo con \func{getsockopt}, ed
+  utilizza per \param{optval} un intero in cui verrà restituito il valore
+  numerico che lo identifica (ad esempio \texttt{IPPROTO\_TCP}).
+
+\item[\constd{SO\_RCVBUF}] questa opzione imposta la dimensione del buffer di
+  ricezione del socket. Prende per \param{optval} un intero indicante il
+  numero di byte. Il valore di default ed il valore massimo che si può
+  specificare come argomento per questa opzione sono impostabili tramiti gli
+  opportuni valori di \func{sysctl} (vedi sez.~\ref{sec:sock_sysctl}).
+
+  Si tenga presente che nel caso di socket TCP il kernel alloca effettivamente
+  una quantità di memoria doppia rispetto a quanto richiesto con
+  \func{setsockopt} per entrambe le opzioni \const{SO\_RCVBUF} e
+  \const{SO\_SNDBUF}. Questo comporta che una successiva lettura con
+  \func{getsockopt} riporterà un valore diverso da quello impostato con
+  \func{setsockopt}.  Questo avviene perché TCP necessita dello spazio in più
+  per mantenere dati amministrativi e strutture interne, e solo una parte
+  viene usata come buffer per i dati, mentre il valore letto da
+  \func{getsockopt} e quello riportato nei vari parametri di
+  \textit{sysctl}\footnote{cioè \sysctlrelfile{net/core}{wmem\_max} e
+    \sysctlrelfile{net/core}{rmem\_max} in \texttt{/proc/sys/net/core} e
+    \sysctlrelfile{net/ipv4}{tcp\_wmem} e \sysctlrelfile{net/ipv4}{tcp\_rmem}
+    in \texttt{/proc/sys/net/ipv4}, vedi sez.~\ref{sec:sock_sysctl}.} indica
+  la memoria effettivamente impiegata.  Si tenga presente inoltre che le
+  modifiche alle dimensioni dei buffer di ricezione e trasmissione, per poter
+  essere effettive, devono essere impostate prima della chiamata alle funzioni
+  \func{listen} o \func{connect}.
+
+\item[\constd{SO\_RCVBUFFORCE}] questa opzione, presente dal kernel 2.6.14, è
+  identica a \const{SO\_RCVBUF} ma consente ad un processo con i privilegi di
+  amministratore (per la precisione con la \textit{capability}
+  \const{CAP\_NET\_ADMIN}) di impostare in valore maggiore del limite di
+  \sysctlrelfile{net/core}{rmem\_max}.
+
+\item[\constd{SO\_RCVLOWAT}] questa opzione imposta il valore che indica il
+  numero minimo di byte che devono essere presenti nel buffer di ricezione
+  perché il kernel passi i dati all'utente, restituendoli ad una \func{read} o
+  segnalando ad una \func{select} (vedi sez.~\ref{sec:TCP_sock_select}) che ci
+  sono dati in ingresso. L'opzione utilizza per \param{optval} un intero che
+  specifica il numero di byte; con Linux questo valore è sempre 1 e può essere
+  cambiato solo con i kernel a partire dal 2.4. Si tenga presente però che per
+  i kernel prima del 2.6.28 sia \func{poll} che \func{select} non supportano
+  questa funzionalità e ritornano comunque, indicando il socket come
+  leggibile, non appena almeno un byte è presente, con una successiva lettura
+  con \func{read} che si blocca fintanto che non diventa disponibile la
+  quantità di byte indicati. Con \func{getsockopt} si può leggere questo
+  valore mentre \func{setsockopt} darà un errore di \errcode{ENOPROTOOPT}
+  quando il cambiamento non è supportato.
+
+\item[\constd{SO\_RCVTIMEO}] l'opzione permette di impostare un tempo massimo
+  sulle operazioni di lettura da un socket, e prende per \param{optval} una
+  struttura di tipo \struct{timeval} (vedi fig.~\ref{fig:sys_timeval_struct})
+  identica a quella usata con \func{select}. Con \func{getsockopt} si può
+  leggere il valore attuale, mentre con \func{setsockopt} si imposta il tempo
+  voluto, usando un valore nullo per \struct{timeval} il timeout viene
+  rimosso. 
+
+  Se l'opzione viene attivata tutte le volte che una delle funzioni di lettura
+  (\func{read}, \func{readv}, \func{recv}, \func{recvfrom} e \func{recvmsg})
+  si blocca in attesa di dati per un tempo maggiore di quello impostato, essa
+  ritornerà un valore -1 e la variabile \var{errno} sarà impostata con un
+  errore di \errcode{EAGAIN} e \errcode{EWOULDBLOCK}, così come sarebbe
+  avvenuto se si fosse aperto il socket in modalità non bloccante.\footnote{in
+    teoria, se il numero di byte presenti nel buffer di ricezione fosse
+    inferiore a quello specificato da \const{SO\_RCVLOWAT}, l'effetto potrebbe
+    essere semplicemente quello di provocare l'uscita delle funzioni di
+    lettura restituendo il numero di byte fino ad allora ricevuti.}
+
+  In genere questa opzione non è molto utilizzata se si ha a che fare con la
+  lettura dei dati, in quanto è sempre possibile usare una \func{select} che
+  consente di specificare un \textit{timeout}; l'uso di \func{select} non
+  consente però di impostare il timeout per l'uso di \func{connect}, per avere
+  il quale si può ricorrere a questa opzione (nel qual caso il raggiungimento
+  del \textit{timeout} restituisce l'errore \errcode{EINPROGRESS}). 
+
+\item[\const{SO\_REUSEADDR}] questa opzione permette di eseguire la funzione
+  \func{bind} su indirizzi locali che siano già in uso da altri socket;
+  l'opzione utilizza per \param{optval} un intero usato come valore logico.
+  Questa opzione modifica il comportamento normale dell'interfaccia dei socket
+  che fa fallire l'esecuzione della funzione \func{bind} con un errore di
+  \errcode{EADDRINUSE} quando l'indirizzo locale (più propriamente il
+  controllo viene eseguito sulla porta) è già in uso da parte di un altro
+  socket.  Maggiori dettagli sul suo funzionamento sono forniti in
+  sez.~\ref{sec:sock_options_main}.
+
+\item[\const{SO\_REUSEPORT}] questa opzione, presente a partire dal kernel
+  3.9, permette di far usare a più socket di tipo \const{AF\_INET} o
+  \const{AF\_INET6} lo stesso indirizzo locale, e costituisce una estensione
+  della precedente \const{SO\_REUSEADDR}.  Maggiori dettagli sul suo
+  funzionamento sono forniti in sez.~\ref{sec:sock_options_main}.
+
+\item[\constd{SO\_RXQ\_OVFL}] questa opzione, presente dal kernel 2.6.33,
+  permette di abilitare o disabilitare sul socket la ricezione di un messaggio
+  ancillare (tratteremo l'argomento in sez.~\ref{sec:net_ancillary_data})
+  contenente un intero senza segno a 32 bit che indica il numero di pacchetti
+  scartati sul socket fra l'ultimo pacchetto ricevuto e questo.  L'opzione
+  utilizza per \param{optval} un intero usato come valore logico.
+
+% TODO documentare SO_RXQ_OVFL, vedi https://lwn.net/Articles/626150/ capire
+% che significa 'questo'
+
+\item[\constd{SO\_SNDLOWAT}] questa opzione imposta il valore che indica il
+  numero minimo di byte che devono essere presenti nel buffer di trasmissione
+  perché il kernel li invii al protocollo successivo, consentendo ad una
+  \func{write} di ritornare o segnalando ad una \func{select} (vedi
+  sez.~\ref{sec:TCP_sock_select}) che è possibile eseguire una scrittura.
+  L'opzione utilizza per \param{optval} un intero che specifica il numero di
+  byte; con Linux questo valore è sempre 1 e non può essere cambiato;
+  \func{getsockopt} leggerà questo valore mentre \func{setsockopt} darà un
+  errore di \errcode{ENOPROTOOPT}.
+
+\item[\constd{SO\_SNDBUF}] questa opzione imposta la dimensione del buffer di
+  trasmissione del socket. Prende per \param{optval} un intero indicante il
+  numero di byte. Il valore di default ed il valore massimo che si possono
+  specificare come argomento per questa opzione sono impostabili
+  rispettivamente tramite gli opportuni valori di \func{sysctl} (vedi
+  sez.~\ref{sec:sock_sysctl}).
+
+\item[\constd{SO\_SNDBUFFORCE}] questa opzione, presente dal kernel 2.6.14, è
+  identica a \const{SO\_SNDBUF} ma consente ad un processo con i privilegi di
+  amministratore (per la precisione con la \textit{capability}
+  \const{CAP\_NET\_ADMIN}) di impostare in valore maggiore del limite di
+  \sysctlrelfile{net/core}{wmem\_max}.
+
+% TODO verificare il timeout con un programma di test
+
+\item[\constd{SO\_SNDTIMEO}] l'opzione permette di impostare un tempo massimo
+  sulle operazioni di scrittura su un socket, ed usa gli stessi valori di
+  \const{SO\_RCVTIMEO}.  In questo caso però si avrà un errore di
+  \errcode{EAGAIN} o \errcode{EWOULDBLOCK} per le funzioni di scrittura
+  \func{write}, \func{writev}, \func{send}, \func{sendto} e \func{sendmsg}
+  qualora queste restino bloccate per un tempo maggiore di quello specificato. 
+
+\item[\constd{SO\_TIMESTAMP}] questa opzione, presente dal kernel 2.6.30,
+  permette di abilitare o disabilitare sul socket la ricezione di un messaggio
+  ancillare di tipo \const{SO\_TIMESTAMP}. Il messaggio viene inviato con
+  livello \const{SOL\_SOCKET} ed nel campo \var{cmsg\_data} (per i dettagli si
+  veda sez.~\ref{sec:net_ancillary_data}) viene impostata una struttura
+  \struct{timeval} che indica il tempo di ricezione dell'ultimo pacchetto
+  passato all'utente.  L'opzione utilizza per \param{optval} un intero usato
+  come valore logico.
+
+% TODO capire meglio la tempistica di questi messaggi ancillari
+% TODO documentare SO_TIMESTAMP e le altre opzioni di timestamping dei 
+% pacchetti, introdotte nel 2.6.30, vedi nei sorgenti del kernel:
+% Documentation/networking/timestamping.txt
+
+\item[\constd{SO\_TYPE}] questa opzione permette di leggere il tipo di socket
+  su cui si opera; funziona solo con \func{getsockopt}, ed utilizza per
+  \param{optval} un intero in cui verrà restituito il valore numerico che lo
+  identifica (ad esempio \const{SOCK\_STREAM}). 
+
+
+\end{basedescript}
+
+
+\subsection{L'uso delle principali opzioni dei socket}
+\label{sec:sock_options_main}
+
+La descrizione sintetica del significato delle opzioni generiche dei socket,
+riportata nell'elenco in sez.~\ref{sec:sock_generic_options}, è
+necessariamente sintetica, alcune di queste però possono essere utilizzate
+per controllare delle funzionalità che hanno una notevole rilevanza nella
+programmazione dei socket.  Per questo motivo faremo in questa sezione un
+approfondimento sul significato delle opzioni generiche più importanti.
+
+
+\constbeg{SO\_KEEPALIVE}
+\subsubsection{L'opzione \const{SO\_KEEPALIVE}}
+
+La prima opzione da approfondire è \const{SO\_KEEPALIVE} che permette di
+tenere sotto controllo lo stato di una connessione. Una connessione infatti
+resta attiva anche quando non viene effettuato alcun traffico su di essa; è
+allora possibile, in caso di una interruzione completa della rete, che la
+caduta della connessione non venga rilevata, dato che sulla stessa non passa
+comunque alcun traffico.
+
+Se si imposta questa opzione, è invece cura del kernel inviare degli appositi
+messaggi sulla rete, detti appunto \textit{keep-alive}, per verificare se la
+connessione è attiva.  L'opzione funziona soltanto con i socket che supportano
+le connessioni (non ha senso per socket UDP ad esempio) e si applica
+principalmente ai socket TCP.
+
+Con le impostazioni di default (che sono riprese da BSD) Linux emette un
+messaggio di \textit{keep-alive} (in sostanza un segmento ACK vuoto, cui sarà
+risposto con un altro segmento ACK vuoto) verso l'altro capo della connessione
+se questa è rimasta senza traffico per più di due ore.  Se è tutto a posto il
+messaggio viene ricevuto e verrà emesso un segmento ACK di risposta, alla cui
+ricezione ripartirà un altro ciclo di attesa per altre due ore di inattività;
+il tutto avviene all'interno del kernel e le applicazioni non riceveranno
+nessun dato.
+
+Qualora ci siano dei problemi di rete si possono invece verificare i due casi
+di terminazione precoce del server già illustrati in
+sez.~\ref{sec:TCP_conn_crash}. Il primo è quello in cui la macchina remota ha
+avuto un crollo del sistema ed è stata riavviata, per cui dopo il riavvio la
+connessione non esiste più.\footnote{si ricordi che un normale riavvio o il
+  crollo dell'applicazione non ha questo effetto, in quanto in tal caso si
+  passa sempre per la chiusura del processo, e questo, come illustrato in
+  sez.~\ref{sec:file_open_close}, comporta anche la regolare chiusura del
+  socket con l'invio di un segmento FIN all'altro capo della connessione.} In
+questo caso all'invio del messaggio di \textit{keep-alive} si otterrà come
+risposta un segmento RST che indica che l'altro capo non riconosce più
+l'esistenza della connessione ed il socket verrà chiuso riportando un errore
+di \errcode{ECONNRESET}.
+
+Se invece non viene ricevuta nessuna risposta (indice che la macchina non è
+più raggiungibile) l'emissione dei messaggi viene ripetuta ad intervalli di 75
+secondi per un massimo di 9 volte\footnote{entrambi questi valori possono
+  essere modificati a livello di sistema (cioè per tutti i socket) con gli
+  opportuni parametri illustrati in sez.~\ref{sec:sock_sysctl} ed a livello di
+  singolo socket con le opzioni \texttt{TCP\_KEEP*} di
+  sez.~\ref{sec:sock_tcp_udp_options}.}  (per un totale di 11 minuti e 15
+secondi) dopo di che, se non si è ricevuta nessuna risposta, il socket viene
+chiuso dopo aver impostato un errore di \errcode{ETIMEDOUT}. Qualora la
+connessione si sia ristabilita e si riceva un successivo messaggio di risposta
+il ciclo riparte come se niente fosse avvenuto.  Infine se si riceve come
+risposta un pacchetto ICMP di destinazione irraggiungibile (vedi
+sez.~\ref{sec:ICMP_protocol}), verrà restituito l'errore corrispondente.
+
+In generale questa opzione serve per individuare una caduta della connessione
+anche quando non si sta facendo traffico su di essa.  Viene usata
+principalmente sui server per evitare di mantenere impegnate le risorse che
+verrebbero dedicate a trattare delle connessioni che in realtà sono già
+terminate (quelle che vengono anche chiamate connessioni
+\textsl{semi-aperte}); in tutti quei casi cioè in cui il server si trova in
+attesa di dati in ingresso su una connessione che non arriveranno mai o perché
+il client sull'altro capo non è più attivo o perché non è più in grado di
+comunicare con il server via rete.
+
+\begin{figure}[!htbp]
+  \footnotesize \centering
+  \begin{minipage}[c]{\codesamplewidth}
+    \includecodesample{listati/TCP_echod_fourth.c}
+  \end{minipage}
+  \normalsize
+  \caption{La sezione della nuova versione del server del servizio
+    \textit{echo} che prevede l'attivazione del \textit{keepalive} sui
+    socket.}
+  \label{fig:echod_keepalive_code}
+\end{figure}
+
+Abilitandola dopo un certo tempo le connessioni effettivamente terminate
+verranno comunque chiuse per cui, utilizzando ad esempio una \func{select}, se
+ne potrà rilevare la conclusione e ricevere il relativo errore. Si tenga
+presente però che non può avere la certezza assoluta che un errore di
+\errcode{ETIMEDOUT} ottenuto dopo aver abilitato questa opzione corrisponda
+necessariamente ad una reale conclusione della connessione, il problema
+potrebbe anche essere dovuto ad un problema di routing che perduri per un
+tempo maggiore di quello impiegato nei vari tentativi di ritrasmissione del
+\textit{keep-alive} (anche se questa non è una condizione molto probabile).
+
+Come esempio dell'utilizzo di questa opzione introduciamo all'interno del
+nostro server per il servizio \textit{echo} la nuova opzione \texttt{-k} che
+permette di attivare il \textit{keep-alive} sui socket; tralasciando la parte
+relativa alla gestione di detta opzione (che si limita ad assegnare ad 1 la
+variabile \var{keepalive}) tutte le modifiche al server sono riportate in
+fig.~\ref{fig:echod_keepalive_code}. Al solito il codice completo è contenuto
+nel file \texttt{TCP\_echod\_fourth.c} dei sorgenti allegati alla guida.
+
+Come si può notare la variabile \var{keepalive} è preimpostata (\texttt{\small
+  8}) ad un valore nullo; essa viene utilizzata sia come variabile logica per
+la condizione (\texttt{\small 14}) che controlla l'attivazione del
+\textit{keep-alive} che come valore dell'argomento \param{optval} della
+chiamata a \func{setsockopt} (\texttt{\small 16}).  A seconda del suo valore
+tutte le volte che un processo figlio viene eseguito in risposta ad una
+connessione verrà pertanto eseguita o meno la sezione (\texttt{\small 14--17})
+che esegue l'impostazione di \const{SO\_KEEPALIVE} sul socket connesso,
+attivando il relativo comportamento.
+\constend{SO\_KEEPALIVE}
+
+
+
+\constbeg{SO\_REUSEADDR}
+\subsubsection{Le opzioni \const{SO\_REUSEADDR} e \const{SO\_REUSEPORT}}
+
+La seconda opzione da approfondire è \constd{SO\_REUSEADDR}, che consente di
+eseguire \func{bind} su un socket anche quando la porta specificata è già in
+uso da parte di un altro socket. Si ricordi infatti che, come accennato in
+sez.~\ref{sec:TCP_func_bind}, normalmente la funzione \func{bind} fallisce con
+un errore di \errcode{EADDRINUSE} se la porta scelta è già utilizzata da un
+altro socket, proprio per evitare che possano essere lanciati due server sullo
+stesso indirizzo e la stessa porta, che verrebbero a contendersi i pacchetti
+aventi quella destinazione.
+
+Esistono però situazioni ed esigenze particolari in cui non si vuole che
+questo comportamento di salvaguardia accada, ed allora si può fare ricorso a
+questa opzione.  La questione è comunque abbastanza complessa in quanto, come
+sottolinea Stevens in \cite{UNP1}, si distinguono ben quattro casi diversi in
+cui è prevista la possibilità di un utilizzo di questa opzione, il che la
+rende una delle più difficili da capire.
+
+Il primo caso in cui si fa ricorso a \const{SO\_REUSEADDR}, che è anche il più
+comune, è quello in cui un server è terminato ma esistono ancora dei processi
+figli che mantengono attiva almeno una connessione remota che utilizza
+l'indirizzo locale, mantenendo occupata la porta. Quando si riesegue il server
+allora questo riceve un errore sulla chiamata a \func{bind} dato che la porta
+è ancora utilizzata in una connessione esistente.\footnote{questa è una delle
+  domande più frequenti relative allo sviluppo, in quanto è piuttosto comune
+  trovarsi in questa situazione quando si sta sviluppando un server che si
+  ferma e si riavvia in continuazione dopo aver fatto modifiche.}  Inoltre se
+si usa il protocollo TCP questo può avvenire anche dopo tutti i processi figli
+sono terminati, dato che una connessione può restare attiva anche dopo la
+chiusura del socket, mantenendosi nello stato \texttt{TIME\_WAIT} (vedi
+sez.~\ref{sec:TCP_time_wait}).
+
+\begin{figure}[!htbp]
+  \footnotesize \centering
+  \begin{minipage}[c]{\codesamplewidth}
+    \includecodesample{listati/sockbindopt.c}
+  \end{minipage}
+  \normalsize
+  \caption{Le sezioni della funzione \texttt{sockbindopt} modificate rispetto al
+    codice della precedente \texttt{sockbind}.} 
+  \label{fig:sockbindopt_code}
+\end{figure}
+
+Usando \const{SO\_REUSEADDR} fra la chiamata a \func{socket} e quella a
+\func{bind} si consente a quest'ultima di avere comunque successo anche se la
+connessione è attiva (o nello stato \texttt{TIME\_WAIT}). È bene però
+ricordare (si riveda quanto detto in sez.~\ref{sec:TCP_time_wait}) che la
+presenza dello stato \texttt{TIME\_WAIT} ha una ragione, ed infatti se si usa
+questa opzione esiste sempre una probabilità, anche se estremamente
+remota,\footnote{perché ciò avvenga infatti non solo devono coincidere gli
+  indirizzi IP e le porte degli estremi della nuova connessione, ma anche i
+  numeri di sequenza dei pacchetti, e questo è estremamente improbabile.}  che
+eventuali pacchetti rimasti intrappolati in una precedente connessione possano
+finire fra quelli di una nuova.
+
+Come esempio di uso di questa connessione abbiamo predisposto una nuova
+versione della funzione \texttt{sockbind} (vedi fig.~\ref{fig:sockbind_code})
+che consenta l'impostazione di questa opzione. La nuova funzione è
+\texttt{sockbindopt}, e le principali differenze rispetto alla precedente sono
+illustrate in fig.~\ref{fig:sockbindopt_code}, dove si sono riportate le
+sezioni di codice modificate rispetto alla versione precedente. Il codice
+completo della funzione si trova, insieme alle altre funzioni di servizio dei
+socket, all'interno del file \texttt{SockUtils.c} dei sorgenti allegati alla
+guida.
+
+In realtà tutto quello che si è fatto è stato introdurre nella nuova funzione
+(\texttt{\small 1}) un nuovo argomento intero, \param{reuse}, che conterrà il
+valore logico da usare nella successiva chiamata (\texttt{\small 14}) a
+\func{setsockopt}. Si è poi aggiunta una sezione (\texttt{\small 13--17}) che
+esegue l'impostazione dell'opzione fra la chiamata a \func{socket} e quella a
+\func{bind}.
+
+\begin{figure}[!htbp] 
+  \footnotesize \centering
+  \begin{minipage}[c]{\codesamplewidth}
+    \includecodesample{listati/TCP_echod_fifth.c}
+  \end{minipage}
+  \normalsize
+  \caption{Il nuovo codice per l'apertura passiva del server \textit{echo} che
+    usa la nuova funzione \texttt{sockbindopt}.}
+  \label{fig:TCP_echod_fifth}
+\end{figure}
+
+A questo punto basterà modificare il  server per utilizzare la nuova
+funzione; in fig.~\ref{fig:TCP_echod_fifth} abbiamo riportato le sezioni
+modificate rispetto alla precedente versione di
+fig.~\ref{fig:TCP_echod_third}. Al solito il codice completo è coi sorgenti
+allegati alla guida, nel file \texttt{TCP\_echod\_fifth.c}.
+
+Anche in questo caso si è introdotta (\texttt{\small 8}) una nuova variabile
+\var{reuse} che consente di controllare l'uso dell'opzione e che poi sarà
+usata (\texttt{\small 14}) come ultimo argomento di \func{setsockopt}. Il
+valore di default di questa variabile è nullo, ma usando l'opzione \texttt{-r}
+nell'invocazione del server (al solito la gestione delle opzioni non è
+riportata in fig.~\ref{fig:TCP_echod_fifth}) se ne potrà impostare ad 1 il
+valore, per cui in tal caso la successiva chiamata (\texttt{\small 13--17}) a
+\func{setsockopt} attiverà l'opzione \const{SO\_REUSEADDR}.
+
+Il secondo caso in cui viene usata \const{SO\_REUSEADDR} è quando si ha una
+macchina cui sono assegnati diversi indirizzi IP (o come suol dirsi
+\textit{multi-homed}) e si vuole porre in ascolto sulla stessa porta un
+programma diverso (o una istanza diversa dello stesso programma) per indirizzi
+IP diversi. Si ricordi infatti che è sempre possibile indicare a \func{bind}
+di collegarsi solo su di un indirizzo specifico; in tal caso se un altro
+programma cerca di riutilizzare la stessa porta (anche specificando un
+indirizzo diverso) otterrà un errore, a meno di non aver preventivamente
+impostato \const{SO\_REUSEADDR}.
+
+Usando questa opzione diventa anche possibile eseguire \func{bind}
+sull'indirizzo generico, e questo permetterà il collegamento per tutti gli
+indirizzi (di quelli presenti) per i quali la porta non risulti occupata da
+una precedente chiamata più specifica. Si tenga presente infatti che con il
+protocollo TCP non è in genere possibile far partire più server che eseguano
+\func{bind} sullo stesso indirizzo e la stessa porta se su di esso c'è già un
+socket in ascolto, cioè ottenere quello che viene chiamato un
+\itindex{completely~duplicate~binding} \textit{completely duplicate binding}
+(per questo è stata introdotta \const{SO\_REUSEPORT}).
+
+Il terzo impiego è simile al precedente e prevede l'uso di \func{bind}
+all'interno dello stesso programma per associare indirizzi locali diversi a
+socket diversi. In genere questo viene fatto per i socket UDP quando è
+necessario ottenere l'indirizzo a cui sono rivolte le richieste del client ed
+il sistema non supporta l'opzione \constd{IP\_RECVDSTADDR};\footnote{nel caso
+  di Linux questa opzione è stata supportata per in certo periodo nello
+  sviluppo del kernel 2.1.x, ma è in seguito stata soppiantata dall'uso di
+  \const{IP\_PKTINFO} (vedi sez.~\ref{sec:sock_ipv4_options}).} in tale modo
+si può sapere a quale socket corrisponde un certo indirizzo.  Non ha senso
+fare questa operazione per un socket TCP dato che su di essi si può sempre
+invocare \func{getsockname} una volta che si è completata la connessione.
+
+Infine il quarto caso è quello in cui si vuole effettivamente ottenere un
+\textit{completely duplicate binding}, quando cioè si vuole eseguire
+\func{bind} su un indirizzo ed una porta che sono già ``\textsl{legati}'' ad
+un altro socket.  Come accennato questo con TCP non è possibile, ed ha anche
+poco senso pensare di mettere in ascolto due server sulla stessa porta. Se
+però si prende in considerazione il traffico in \textit{multicast}, diventa
+assolutamente normale che i pacchetti provenienti dal traffico in
+\textit{multicast} possano essere ricevuti da più applicazioni o da diverse
+istanze della stessa applicazione sulla stessa porte di un indirizzo di
+\textit{multicast}.
+
+Un esempio classico è quello di uno streaming di dati (audio, video, ecc.) in
+cui l'uso del \textit{multicast} consente di trasmettere un solo pacchetto da
+recapitare a tutti i possibili destinatari (invece di inviarne un duplicato a
+ciascuno); in questo caso è perfettamente logico aspettarsi che sulla stessa
+macchina più utenti possano lanciare un programma che permetta loro di
+ricevere gli stessi dati, e quindi effettuare un \textit{completely duplicate
+  binding}.
+
+In questo caso utilizzando \const{SO\_REUSEADDR} si può consentire ad una
+applicazione eseguire \func{bind} sulla stessa porta ed indirizzo usata da
+un'altra, così che anche essa possa ricevere gli stessi pacchetti. Come detto
+la cosa non è possibile con i socket TCP (per i quali il \textit{multicast}
+comunque non è applicabile), ma lo è per quelli UDP che è il protocollo
+normalmente in uso da parte di queste applicazioni. La regola è che quando si
+hanno più applicazioni che hanno eseguito \func{bind} sulla stessa porta, di
+tutti pacchetti destinati ad un indirizzo di \textit{broadcast} o di
+\textit{multicast} viene inviata una copia a ciascuna applicazione. Non è
+definito invece cosa accade qualora il pacchetto sia destinato ad un indirizzo
+normale (\textit{unicast}).
+
+% TODO documentare SO_REUSEPORT, vedi https://lwn.net/Articles/542260/
+
+\constbeg{SO\_REUSEPORT}
+
+Esistono però dei casi, in particolare per l'uso di programmi
+\textit{multithreaded}, in cui può servire un \textit{completely duplicate
+  binding} anche per delle ordinarie connessioni TCP.  Per supportare queste
+esigenze a partire dal kernel 3.9 è stata introdotta un'altra opzione,
+\const{SO\_REUSEPORT} (già presente in altri sistemi come BSD), che consente
+di eseguire il \textit{completely duplicate binding}, fintanto che essa venga
+specificata per tutti i socket interessati. Come per \const{SO\_REUSEADDR}
+sarà possibile usare l'opzione su un socket legato allo stesso indirizzo e
+porta solo se il programma che ha eseguito il primo \func{bind} ha impostato
+questa opzione.
+
+Nel caso di \const{SO\_REUSEPORT} oltre al fatto che l'opzione deve essere
+attivata sul socket prima di chiamare \func{bind} ed attiva su tutti i socket
+con \textit{completely duplicate binding}, è richiesto pure che tutti i
+processi che si mettono in ascolto sullo stesso indirizzo e porta abbiano lo
+stesso \ids{UID} effettivo, per evitare che un altro utente possa ottenere il
+relativo traffico (eseguendo quello che viene definito \textit{port hijacking}
+o \textit{port stealing}). L'opzione utilizza per \param{optval} un intero
+usato come valore logico.
+
+L'opzione si usa sia per socket TCP che UDP, nel primo caso consente un uso
+distribuito di \func{accept} in una applicazione \textit{multithreaded}
+passando un diverso \textit{listening socket} ad ogni thread, cosa che
+migliora le prestazioni rispetto all'approccio tradizionale di usare un thread
+per usare \func{accept} e distribuire le connessioni agli altri o avere più
+thread che competono per usare \func{accept} sul socket. Nel caso di UDP
+l'opzione consente di distribuire meglio i pacchetti su più processi o thread,
+rispetto all'approccio tradizionale di far competere gli stessi per l'accesso
+in ricezione al socket.
+
+% TODO documentare SO_REUSEPORT introdotta con il kernel 3.9, vedi
+% http://git.kernel.org/linus/c617f398edd4db2b8567a28e899a88f8f574798d TODO:
+% in cosa differisce da REUSEADDR?
+
+\constend{SO\_REUSEPORT}
+\constend{SO\_REUSEADDR}
+
+
+\constbeg{SO\_LINGER}
+\subsubsection{L'opzione \const{SO\_LINGER}}
+
+La terza opzione da approfondire è \const{SO\_LINGER}; essa, come il nome
+suggerisce, consente di ``\textsl{indugiare}'' nella chiusura di un socket. Il
+comportamento standard sia di \func{close} che \func{shutdown} è infatti
+quello di terminare immediatamente dopo la chiamata, mentre il procedimento di
+chiusura della connessione (o di un lato di essa) ed il rispettivo invio sulla
+rete di tutti i dati ancora presenti nei buffer, viene gestito in sottofondo
+dal kernel.
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{0.80\textwidth}
+    \includestruct{listati/linger.h}
+  \end{minipage}
+  \caption{La struttura \structd{linger} richiesta come valore dell'argomento
+    \param{optval} per l'impostazione dell'opzione dei socket
+    \const{SO\_LINGER}.}
+  \label{fig:sock_linger_struct}
+\end{figure}
+
+L'uso di \const{SO\_LINGER} con \func{setsockopt} permette di modificare (ed
+eventualmente ripristinare) questo comportamento in base ai valori passati nei
+campi della struttura \struct{linger}, illustrata in
+fig.~\ref{fig:sock_linger_struct}.  Fintanto che il valore del campo
+\var{l\_onoff} di \struct{linger} è nullo la modalità che viene impostata
+(qualunque sia il valore di \var{l\_linger}) è quella standard appena
+illustrata; questa combinazione viene utilizzata per riportarsi al
+comportamento normale qualora esso sia stato cambiato da una precedente
+chiamata.
+
+Se si utilizza un valore di \var{l\_onoff} diverso da zero, il comportamento
+alla chiusura viene a dipendere dal valore specificato per il campo
+\var{l\_linger}; se quest'ultimo è nullo l'uso delle funzioni \func{close} e
+\func{shutdown} provoca la terminazione immediata della connessione: nel caso
+di TCP cioè non viene eseguito il procedimento di chiusura illustrato in
+sez.~\ref{sec:TCP_conn_term}, ma tutti i dati ancora presenti nel buffer
+vengono immediatamente scartati e sulla rete viene inviato un segmento di RST
+che termina immediatamente la connessione.
+
+Un esempio di questo comportamento si può abilitare nel nostro client del
+servizio \textit{echo} utilizzando l'opzione \texttt{-r}; riportiamo in
+fig.~\ref{fig:TCP_echo_sixth} la sezione di codice che permette di introdurre
+questa funzionalità; al solito il codice completo è disponibile nei sorgenti
+allegati.
+
+\begin{figure}[!htbp] 
+  \footnotesize \centering
+  \begin{minipage}[c]{\codesamplewidth}
+    \includecodesample{listati/TCP_echo_sixth.c}
+  \end{minipage}
+  \normalsize
+  \caption{La sezione del codice del client \textit{echo} che imposta la
+    terminazione immediata della connessione in caso di chiusura.}
+  \label{fig:TCP_echo_sixth}
+\end{figure}
+
+La sezione indicata viene eseguita dopo aver effettuato la connessione e prima
+di chiamare la funzione di gestione, cioè fra le righe (\texttt{\small 12}) e
+(\texttt{\small 13}) del precedente esempio di fig.~\ref{fig:TCP_echo_fifth}.
+Il codice si limita semplicemente a controllare (\texttt{\small 3}) il
+valore della variabile \var{reset} che assegnata nella gestione delle opzioni
+in corrispondenza all'uso di \texttt{-r} nella chiamata del client. Nel caso
+questa sia diversa da zero vengono impostati (\texttt{\small 5--6}) i valori
+della struttura \var{ling} che permettono una terminazione immediata della
+connessione. Questa viene poi usata nella successiva (\texttt{\small 7})
+chiamata a \func{setsockopt}. Al solito si controlla (\texttt{\small 7--10})
+il valore di ritorno e si termina il programma in caso di errore, stampandone
+il valore.
+
+Infine l'ultima possibilità, quella in cui si utilizza effettivamente
+\const{SO\_LINGER} per \textsl{indugiare} nella chiusura, è quella in cui sia
+\var{l\_onoff} che \var{l\_linger} hanno un valore diverso da zero. Se si
+esegue l'impostazione con questi valori sia \func{close} che \func{shutdown}
+si bloccano, nel frattempo viene eseguita la normale procedura di conclusione
+della connessione (quella di sez.~\ref{sec:TCP_conn_term}) ma entrambe le
+funzioni non ritornano fintanto che non si sia concluso il procedimento di
+chiusura della connessione, o non sia passato un numero di
+secondi\footnote{questa è l'unità di misura indicata da POSIX ed adottata da
+  Linux, altri kernel possono usare unità di misura diverse, oppure usare il
+  campo \var{l\_linger} come valore logico (ignorandone il valore) per rendere
+  (quando diverso da zero) \func{close} e \func{shutdown} bloccanti fino al
+  completamento della trasmissione dei dati sul buffer.}  pari al valore
+specificato in \var{l\_linger}.
+
+\constend{SO\_LINGER}
+
+
+
+\subsection{Le opzioni per il protocollo IPv4}
+\label{sec:sock_ipv4_options}
+
+Il secondo insieme di opzioni dei socket che tratteremo è quello relativo ai
+socket che usano il protocollo IPv4; come per le precedenti opzioni generiche
+una descrizione di esse è disponibile nella settima sezione delle pagine di
+manuale, nel caso specifico la documentazione si può consultare con
+\texttt{man 7 ip}.  
+
+\begin{table}[!htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|c|c|c|l|p{4.8cm}|}
+    \hline
+    \textbf{Opzione}&\texttt{get}&\texttt{set}&\textbf{flag}&\textbf{Tipo}&
+                    \textbf{Descrizione}\\
+    \hline
+    \hline
+    \const{IP\_ADD\_MEMBERSHIP} &         &$\bullet$&   &\struct{ip\_mreqn}& 
+      Si unisce a un gruppo di \textit{multicast}.\\
+    \const{IP\_ADD\_SOURCE\_MEMBERSHIP} & &$\bullet$&   &\struct{ip\_mreq\_source}& 
+      Si unisce a un gruppo di \textit{multicast} per una sorgente.\\
+    \const{IP\_BLOCK\_SOURCE} & &$\bullet$&   &\struct{ip\_mreq\_source}& 
+      Smette di ricevere dati di \textit{multicast} per una sorgente.\\
+    \const{IP\_DROP\_MEMBERSHIP}&         &$\bullet$&   &\struct{ip\_mreqn}& 
+      Si sgancia da un gruppo di \textit{multicast}.\\
+    \const{IP\_DROP\_SOURCE\_MEMBERSHIP}& &$\bullet$&   &\struct{ip\_mreq\_source}& 
+      Si sgancia da un gruppo di \textit{multicast} per una sorgente.\\
+    \const{IP\_FREEBIND}       &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
+      Abilita il \textit{binding} a un indirizzo IP non locale ancora non assegnato.\\
+    \const{IP\_HDRINCL}         &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
+      Passa l'intestazione di IP nei dati.\\
+    \const{IP\_MINTTL}          &$\bullet$&$\bullet$&   &\texttt{int}& 
+      Imposta il valore minimo del TTL per i pacchetti accettati.\\ 
+    \const{IP\_MSFILTER}        &$\bullet$&$\bullet$&   &\struct{ip\_msfilter}& 
+      Accesso completo all'interfaccia per il filtraggio delle sorgenti
+      \textit{multicast}.\\  
+    \const{IP\_MTU}             &$\bullet$&         &         &\texttt{int}& 
+      Legge il valore attuale della MTU.\\
+    \const{IP\_MTU\_DISCOVER}   &$\bullet$&$\bullet$&         &\texttt{int}& 
+      Imposta il \textit{Path MTU Discovery}.\\
+    \const{IP\_MULTICAST\_ALL}  &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
+      Imposta l'interfaccia locale di un socket \textit{multicast}.\\ 
+    \const{IP\_MULTICAST\_IF}   &         &$\bullet$&   &\struct{ip\_mreqn}& 
+      Imposta l'interfaccia locale di un socket \textit{multicast}.\\ 
+    \const{IP\_MULTICAST\_LOOP} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
+      Controlla il reinvio a se stessi dei dati di \textit{multicast}.\\ 
+    \const{IP\_MULTICAST\_TTL}  &$\bullet$&$\bullet$&         &\texttt{int}& 
+      Imposta il TTL per i pacchetti \textit{multicast}.\\
+    \const{IP\_NODEFRAG}        &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+      Disabilita il riassemblaggio di pacchetti frammentati.\\
+    \const{IP\_OPTIONS}         &$\bullet$&$\bullet$&&\texttt{void *}& %??? 
+      Imposta o riceve le opzioni di IP.\\
+    \const{IP\_PKTINFO}         &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
+      Abilita i messaggi di informazione.\\
+    \const{IP\_RECVERR}         &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
+      Abilita i messaggi di errore affidabili.\\
+    \const{IP\_RECVOPTS}        &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
+      Passa un messaggio con le opzioni IP.\\
+    \const{IP\_RECVORIGSTADDR}  &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
+      Abilita i messaggi con l'indirizzo di destinazione originale.\\
+    \const{IP\_RECVTOS}         &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
+      Passa un messaggio col campo TOS.\\
+    \const{IP\_RECVTTL}         &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
+      Abilita i messaggi col campo TTL.\\
+    \const{IP\_RETOPTS}         &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
+      Abilita i messaggi con le opzioni IP non trattate.\\
+    \const{IP\_ROUTER\_ALERT}   &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
+      Imposta l'opzione \textit{IP router alert} sui pacchetti.\\
+    \const{IP\_TOS}             &$\bullet$&$\bullet$&         &\texttt{int}& 
+      Imposta il valore del campo TOS.\\
+    \const{IP\_TRANSPARENT}     &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
+      Abilita un \textit{proxing} trasparente sul socket.\\
+    \const{IP\_TTL}             &$\bullet$&$\bullet$&         &\texttt{int}& 
+      Imposta il valore del campo TTL.\\
+    \const{IP\_UNBLOCK\_SOURCE} & &$\bullet$&   &\struct{ip\_mreq\_source}& 
+      Ricomincia a ricevere dati di \textit{multicast} per una sorgente.\\
+   \hline
+  \end{tabular}
+  \caption{Le opzioni disponibili al livello \const{IPPROTO\_IP}.} 
+  \label{tab:sock_opt_iplevel}
+\end{table}
+
+Se si vuole operare su queste opzioni generiche il livello da utilizzare è
+\constd{IPPROTO\_IP} (o l'equivalente \const{SOL\_IP}); si è riportato un
+elenco di queste opzioni in tab.~\ref{tab:sock_opt_iplevel}.  Le costanti
+indicanti le opzioni, e tutte le altre costanti ad esse collegate, sono
+definite in \headfiled{netinet/ip.h}, ed accessibili includendo detto file.
+
+Le descrizioni riportate in tab.~\ref{tab:sock_opt_iplevel} sono estremamente
+succinte, una maggiore quantità di dettagli sulle varie opzioni è fornita nel
+seguente elenco:
+\begin{basedescript}{\desclabelwidth{2.0cm}\desclabelstyle{\nextlinelabel}}
+\item[\constd{IP\_ADD\_MEMBERSHIP}] L'opzione consente di unirsi ad gruppo di
+  \textit{multicast}, e può essere usata solo con \func{setsockopt}.
+  L'argomento \param{optval} in questo caso deve essere una struttura di tipo
+  \struct{ip\_mreqn}, illustrata in fig.~\ref{fig:ip_mreqn_struct}, che
+  permette di indicare, con il campo \var{imr\_multiaddr} l'indirizzo del
+  gruppo di \textit{multicast} a cui ci si vuole unire, con il campo
+  \var{imr\_address} l'indirizzo dell'interfaccia locale con cui unirsi al
+  gruppo di \textit{multicast} e con \var{imr\_ifindex} l'indice
+  dell'interfaccia da utilizzare (un valore nullo indica una interfaccia
+  qualunque).
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{0.90\textwidth}
+    \includestruct{listati/ip_mreqn.h}
+  \end{minipage}
+  \caption{La struttura \structd{ip\_mreqn} utilizzata per unirsi a un gruppo di
+    \textit{multicast}.}
+  \label{fig:ip_mreqn_struct}
+\end{figure}
+
+Questa struttura è presente a partire dal kernel 2.2, per compatibilità è
+possibile utilizzare anche un argomento di tipo \struct{ip\_mreq}, presente
+fino dal kernel 1.2, che differisce da essa soltanto per l'assenza del campo
+\var{imr\_ifindex}; il kernel riconosce il tipo di struttura in base alla
+differente dimensione passata in \param{optlen}. 
+
+\item[\constd{IP\_ADD\_SOURCE\_MEMBERSHIP}] L'opzione consente di unirsi ad
+  gruppo di \textit{multicast}, ricevendo i dati solo da una sorgente
+  specifica; come \const{IP\_ADD\_MEMBERSHIP} può essere usata solo con
+  \func{setsockopt}.
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{0.90\textwidth}
+    \includestruct{listati/ip_mreq_source.h}
+  \end{minipage}
+  \caption{La struttura \structd{ip\_mreqn} utilizzata per unirsi a un gruppo di
+    \textit{multicast} per una specifica sorgente.}
+  \label{fig:ip_mreq_source_struct}
+\end{figure}
+
+L'argomento \param{optval} in questo caso è una struttura
+\struct{ip\_mreq\_source} illustrata in fig.~\ref{fig:ip_mreq_source_struct},
+dove il campo \var{imr\_multiaddr} è l'indirizzo del gruppo di
+\textit{multicast}, il campo \var{imr\_interface} l'indirizzo dell'interfaccia
+locale che deve essere usata per aggiungersi al gruppo di \textit{multicast} e
+il campo \var{imr\_sourceaddr} l'indirizzo della sorgente da cui
+l'applicazione vuole ricevere i dati. L'opzione può essere ripetuta più volte
+per collegarsi a diverse sorgenti.
+
+\item[\constd{IP\_BLOCK\_SOURCE}] Questa opzione, disponibile dal kernel
+  2.4.22, consente di smettere di ricevere dati di \textit{multicast} dalla
+  sorgente (e relativo gruppo) specificati dalla struttura
+  \struct{ip\_mreq\_source} (vedi fig.~\ref{fig:ip_mreq_source_struct})
+  passata come argomento \param{optval}. L'opzione è utilizzabile solo se si è
+  già registrati nel gruppo di \textit{multicast} indicato con un precedente
+  utilizzo di \const{IP\_ADD\_MEMBERSHIP} o
+  \const{IP\_ADD\_SOURCE\_MEMBERSHIP}.
+
+\item[\constd{IP\_DROP\_MEMBERSHIP}] Lascia un gruppo di \textit{multicast},
+  prende per \param{optval} la stessa struttura \struct{ip\_mreqn} (o
+  \struct{ip\_mreq}) usata per \const{IP\_ADD\_MEMBERSHIP} (vedi
+  fig.~\ref{fig:ip_mreqn_struct}).
+
+\item[\constd{IP\_DROP\_SOURCE\_MEMBERSHIP}] Lascia un gruppo di
+  \textit{multicast} per una specifica sorgente, prende per \param{optval} la
+  stessa struttura \struct{ip\_mreq\_source} usata per
+  \const{IP\_ADD\_SOURCE\_MEMBERSHIP} (vedi
+  fig.~\ref{fig:ip_mreq_source_struct}). Se ci si è registrati per più
+  sorgenti nello stesso gruppo, si continuerà a ricevere dati sulle altre. Per
+  smettere di ricevere dati da tutte le sorgenti occorre usare l'opzione
+  \const{IP\_LEAVE\_GROUP}.
+
+\item[\constd{IP\_FREEBIND}] Se abilitata questa opzione, disponibile dal
+  kernel 2.4, consente di usare \func{bind} anche su un indirizzo IP non
+  locale o che ancora non è stato assegnato. Questo permette ad una
+  applicazione di mettersi in ascolto su un socket prima che l'interfaccia
+  sottostante o l'indirizzo che questa deve usare sia stato configurato. È
+  l'equivalente a livello di singolo socket dell'uso della \textit{sysctl}
+  \texttt{ip\_nonlocal\_bind} che vedremo in
+  sez.~\ref{sec:sock_ipv4_sysctl}. Prende per
+  \param{optval} un intero usato come valore logico.
+
+\item[\constd{IP\_HDRINCL}] Se viene abilitata questa opzione, presente dal
+  kernel 2.0, l'utente deve fornire lui stesso l'intestazione del protocollo
+  IP in testa ai propri dati. L'opzione è valida soltanto per socket di tipo
+  \const{SOCK\_RAW}, e quando utilizzata eventuali valori impostati con
+  \const{IP\_OPTIONS}, \const{IP\_TOS} o \const{IP\_TTL} sono ignorati. In
+  ogni caso prima della spedizione alcuni campi dell'intestazione vengono
+  comunque modificati dal kernel, torneremo sull'argomento in
+  sez.~\ref{sec:socket_raw}.  Prende per \param{optval} un intero usato come
+  valore logico.
+
+\item[\constd{IP\_MSFILTER}] L'opzione, introdotta con il kernel 2.4.22,
+  fornisce accesso completo all'interfaccia per il filtraggio delle sorgenti
+  di \textit{multicast} (il cosiddetto \textit{multicast source filtering},
+  definito dall'\href{http://www.ietf.org/rfc/rfc3376.txt}{RFC~3376}).
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{0.90\textwidth}
+    \includestruct{listati/ip_msfilter.h}
+  \end{minipage}
+  \caption{La struttura \structd{ip\_msfilter} utilizzata per il
+    \textit{multicast source filtering}.}
+  \label{fig:ip_msfilter_struct}
+\end{figure}
+
+L'argomento \param{optval} deve essere una struttura di tipo
+\struct{ip\_msfilter} (illustrata in fig.~\ref{fig:ip_msfilter_struct}); il
+campo \var{imsf\_multiaddr} indica l'indirizzo del gruppo di
+\textit{multicast}, il campo \var{imsf\_interface} l'indirizzo
+dell'interfaccia locale, il campo \var{imsf\_mode} indica la modalità di
+filtraggio e con i campi \var{imsf\_numsrc} e \var{imsf\_slist}
+rispettivamente la lunghezza della lista, e la lista stessa, degli indirizzi
+sorgente.
+
+Come ausilio all'uso di questa opzione sono disponibili le macro
+\macro{MCAST\_INCLUDE} e \macro{MCAST\_EXCLUDE} che si possono usare per
+\var{imsf\_mode}. Inoltre si può usare la macro
+\macro{IP\_MSFILTER\_SIZE}\texttt{(\textsf{n})} per determinare il valore
+di \param{optlen} con una struttura \struct{ip\_msfilter} contenente
+\texttt{\textsf{n}} sorgenti in \var{imsf\_slist}.
+
+\item[\constd{IP\_MINTTL}] L'opzione, introdotta con il kernel 2.6.34, imposta
+  un valore minimo per il campo \textit{Time to Live} dei pacchetti associati
+  al socket su cui è attivata, che se non rispettato ne causa lo scarto
+  automatico. L'opzione è nata per implementare
+  l'\href{http://www.ietf.org/rfc/rfc5082.txt}{RFC~5082} che la prevede come
+  forma di protezione per i router che usano il protocollo BGP poiché questi,
+  essendo in genere adiacenti, possono, impostando un valore di 255, scartare
+  automaticamente tutti gli eventuali pacchetti falsi creati da un attacco a
+  questo protocollo, senza doversi curare di verificarne la
+  validità.\footnote{l'attacco viene in genere portato per causare un
+    \textit{Denial of Service} aumentando il consumo di CPU del router nella
+    verifica dell'autenticità di un gran numero di pacchetti falsi; questi,
+    arrivando da sorgenti diverse da un router adiacente, non potrebbero più
+    avere un TTL di 255 anche qualora questo fosse stato il valore di
+    partenza, e l'impostazione dell'opzione consente di scartarli senza carico
+    aggiuntivo sulla CPU (che altrimenti dovrebbe calcolare una checksum).}
+
+\itindbeg{Path~MTU}
+\item[\constd{IP\_MTU}] Permette di leggere il valore della \textit{Path MTU}
+  del socket.  L'opzione richiede per \param{optval} un intero che conterrà il
+  valore della \textit{Path MTU} in byte.  Questa è una opzione introdotta con
+  i kernel della serie 2.2.x, ed è specifica di Linux.
+
+  È tramite questa opzione che un programma può leggere, quando si è avuto un
+  errore di \errval{EMSGSIZE}, il valore della MTU corrente del socket. Si
+  tenga presente che per poter usare questa opzione, oltre ad avere abilitato
+  la scoperta della \textit{Path MTU}, occorre che il socket sia stato
+  esplicitamente connesso con \func{connect}. 
+
+  Ad esempio con i socket UDP si può ottenere una stima iniziale della
+  \textit{Path MTU} eseguendo prima una \func{connect} verso la destinazione,
+  e poi usando \func{getsockopt} con questa opzione. Si può anche avviare
+  esplicitamente il procedimento di scoperta inviando un pacchetto di grosse
+  dimensioni (che verrà scartato) e ripetendo l'invio coi dati aggiornati. Si
+  tenga infine conto che durante il procedimento i pacchetti iniziali possono
+  essere perduti, ed è compito dell'applicazione gestirne una eventuale
+  ritrasmissione.
+
+\item[\constd{IP\_MTU\_DISCOVER}] Questa è una opzione introdotta con i kernel
+  della serie 2.2.x, ed è specifica di Linux.  L'opzione permette di scrivere
+  o leggere le impostazioni della modalità usata per la determinazione della
+  \textit{Path MTU} (vedi sez.~\ref{sec:net_lim_dim}) del
+  socket. L'opzione prende per \param{optval} un valore intero che indica la
+  modalità usata, da specificare con una delle costanti riportate in
+  tab.~\ref{tab:sock_ip_mtu_discover}.
+
+  \begin{table}[!htb]
+    \centering
+    \footnotesize
+    \begin{tabular}[c]{|l|r|p{7cm}|}
+      \hline
+      \multicolumn{2}{|c|}{\textbf{Valore}}&\textbf{Significato} \\
+      \hline
+      \hline
+      \constd{IP\_PMTUDISC\_DONT}&0& Non effettua la ricerca dalla \textit{Path
+                                     MTU}.\\
+      \constd{IP\_PMTUDISC\_WANT}&1& Utilizza il valore impostato per la rotta
+                                     utilizzata dai pacchetti (dal comando
+                                     \texttt{route}).\\ 
+      \constd{IP\_PMTUDISC\_DO}  &2& Esegue la procedura di determinazione
+                                     della \textit{Path MTU} come richiesto
+                                     dall'\href{http://www.ietf.org/rfc/rfc1191.txt}{RFC~1191}.\\ 
+      \constd{IP\_PMTUDISC\_PROBE}&?& .\\
+      \hline
+    \end{tabular}
+    \caption{Valori possibili per l'argomento \param{optval} di
+      \const{IP\_MTU\_DISCOVER}.} 
+    \label{tab:sock_ip_mtu_discover}
+  \end{table}
+
+  Il valore di default applicato ai socket di tipo \const{SOCK\_STREAM} è
+  determinato dal parametro \texttt{ip\_no\_pmtu\_disc} (vedi
+  sez.~\ref{sec:sock_sysctl}), mentre per tutti gli altri socket di default la
+  ricerca è disabilitata ed è responsabilità del programma creare pacchetti di
+  dimensioni appropriate e ritrasmettere eventuali pacchetti persi. Se
+  l'opzione viene abilitata, il kernel si incaricherà di tenere traccia
+  automaticamente della \textit{Path MTU} verso ciascuna destinazione, e
+  rifiuterà immediatamente la trasmissione di pacchetti di dimensioni maggiori
+  della MTU con un errore di \errval{EMSGSIZE}.\footnote{in caso contrario la
+    trasmissione del pacchetto sarebbe effettuata, ottenendo o un fallimento
+    successivo della trasmissione, o la frammentazione dello stesso.}
+\itindend{Path~MTU}
+
+\item[\constd{IP\_MULTICAST\_IF}] Imposta l'interfaccia locale per l'utilizzo
+  del \textit{multicast}, ed utilizza come \param{optval} le stesse strutture
+  \struct{ip\_mreqn} o \struct{ip\_mreq} delle due precedenti opzioni.
+
+\item[\constd{IP\_MULTICAST\_LOOP}] L'opzione consente di decidere se i dati
+  che si inviano su un socket usato con il \textit{multicast} vengano ricevuti
+  anche sulla stessa macchina da cui li si stanno inviando.  Prende per
+  \param{optval} un intero usato come valore logico.
+
+  In generale se si vuole che eventuali client possano ricevere i dati che si
+  inviano occorre che questa funzionalità sia abilitata (come avviene di
+  default). Qualora però non si voglia generare traffico per dati che già sono
+  disponibili in locale l'uso di questa opzione permette di disabilitare
+  questo tipo di traffico.
+
+\item[\constd{IP\_MULTICAST\_TTL}] L'opzione permette di impostare o leggere il
+  valore del campo TTL per i pacchetti \textit{multicast} in uscita associati
+  al socket. È importante che questo valore sia il più basso possibile, ed il
+  default è 1, che significa che i pacchetti non potranno uscire dalla rete
+  locale. Questa opzione consente ai programmi che lo richiedono di superare
+  questo limite.  L'opzione richiede per
+  \param{optval} un intero che conterrà il valore del TTL.
+% TODO chiarire quale è la struttura \struct{ip\_mreq}
+
+\item[\constd{IP\_OPTIONS}] l'opzione permette di impostare o leggere le
+  opzioni del protocollo IP (si veda sez.~\ref{sec:IP_options}). L'opzione
+  prende come valore dell'argomento \param{optval} un puntatore ad un buffer
+  dove sono mantenute le opzioni, mentre \param{optlen} indica la dimensione
+  di quest'ultimo. Quando la si usa con \func{getsockopt} vengono lette le
+  opzioni IP utilizzate per la spedizione, quando la si usa con
+  \func{setsockopt} vengono impostate le opzioni specificate. L'uso di questa
+  opzione richiede una profonda conoscenza del funzionamento del protocollo,
+  torneremo in parte sull'argomento in sez.~\ref{sec:sock_IP_options}.
+
+\item[\constd{IP\_PKTINFO}] Quando abilitata l'opzione permette di ricevere
+  insieme ai pacchetti un messaggio ancillare (vedi
+  sez.~\ref{sec:net_ancillary_data}) di tipo \const{IP\_PKTINFO} contenente
+  una struttura \struct{pktinfo} (vedi fig.~\ref{fig:sock_pktinfo_struct}) che
+  mantiene una serie di informazioni riguardo i pacchetti in arrivo. In
+  particolare è possibile conoscere l'interfaccia su cui è stato ricevuto un
+  pacchetto (nel campo \var{ipi\_ifindex}),\footnote{in questo campo viene
+    restituito il valore numerico dell'indice dell'interfaccia,
+    sez.~\ref{sec:sock_ioctl_netdevice}.} l'indirizzo locale da esso
+  utilizzato (nel campo \var{ipi\_spec\_dst}) e l'indirizzo remoto dello
+  stesso (nel campo \var{ipi\_addr}).
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{0.80\textwidth}
+    \includestruct{listati/pktinfo.h}
+  \end{minipage}
+  \caption{La struttura \structd{pktinfo} usata dall'opzione
+    \const{IP\_PKTINFO} per ricavare informazioni sui pacchetti di un socket
+    di tipo \const{SOCK\_DGRAM}.}
+  \label{fig:sock_pktinfo_struct}
+\end{figure}
+
+
+L'opzione è utilizzabile solo per socket di tipo \const{SOCK\_DGRAM}. Questa è
+una opzione introdotta con i kernel della serie 2.2.x, ed è specifica di
+Linux;\footnote{non dovrebbe pertanto essere utilizzata se si ha a cuore la
+  portabilità.} essa permette di sostituire le opzioni \const{IP\_RECVDSTADDR}
+e \const{IP\_RECVIF} presenti in altri Unix (la relativa informazione è quella
+ottenibile rispettivamente dai campi \var{ipi\_addr} e \var{ipi\_ifindex} di
+\struct{pktinfo}). 
+
+L'opzione prende per \param{optval} un intero usato come valore logico, che
+specifica soltanto se insieme al pacchetto deve anche essere inviato o
+ricevuto il messaggio \const{IP\_PKTINFO} (vedi
+sez.~\ref{sec:net_ancillary_data}); il messaggio stesso dovrà poi essere
+letto o scritto direttamente con \func{recvmsg} e \func{sendmsg} (vedi
+sez.~\ref{sec:net_sendmsg}).
+
+\item[\constd{IP\_RECVERR}] Questa è una opzione introdotta con i kernel della
+  serie 2.2.x, ed è specifica di Linux. Essa permette di usufruire di un
+  meccanismo affidabile per ottenere un maggior numero di informazioni in caso
+  di errori. Se l'opzione è abilitata tutti gli errori generati su un socket
+  vengono memorizzati su una coda, dalla quale poi possono essere letti con
+  \func{recvmsg} (vedi sez.~\ref{sec:net_sendmsg}) come messaggi ancillari
+  (torneremo su questo in sez.~\ref{sec:net_ancillary_data}) di tipo
+  \const{IP\_RECVERR}.  L'opzione richiede per \param{optval} un intero usato
+  come valore logico e non è applicabile a socket di tipo
+  \const{SOCK\_STREAM}.
+
+\item[\constd{IP\_RECVOPTS}] Quando abilitata l'opzione permette di ricevere
+  insieme ai pacchetti un messaggio ancillare (vedi
+  sez.~\ref{sec:net_ancillary_data}) di tipo \const{IP\_OPTIONS}, contenente
+  le opzioni IP del protocollo (vedi sez.~\ref{sec:IP_options}). Le
+  intestazioni di instradamento e le altre opzioni sono già riempite con i
+  dati locali. L'opzione richiede per \param{optval} un intero usato come
+  valore logico.  L'opzione non è supportata per socket di tipo
+  \const{SOCK\_STREAM}.
+
+\item[\constd{IP\_RECVTOS}] Quando abilitata l'opzione permette di ricevere
+  insieme ai pacchetti un messaggio ancillare (vedi
+  sez.~\ref{sec:net_ancillary_data}) di tipo \const{IP\_TOS}, che contiene un
+  byte con il valore del campo \textit{Type of Service} dell'intestazione IP
+  del pacchetto stesso (vedi sez.~\ref{sec:IP_header}).  Prende per
+  \param{optval} un intero usato come valore logico.
+
+\item[\constd{IP\_RECVTTL}] Quando abilitata l'opzione permette di ricevere
+  insieme ai pacchetti un messaggio ancillare (vedi
+  sez.~\ref{sec:net_ancillary_data}) di tipo \const{IP\_RECVTTL}, contenente
+  un byte con il valore del campo \textit{Time to Live} dell'intestazione IP
+  (vedi sez.~\ref{sec:IP_header}).  L'opzione richiede per \param{optval} un
+  intero usato come valore logico. L'opzione non è supportata per socket di
+  tipo \const{SOCK\_STREAM}.
+
+\item[\constd{IP\_RETOPTS}] Identica alla precedente \const{IP\_RECVOPTS}, ma
+  in questo caso restituisce i dati grezzi delle opzioni, senza che siano
+  riempiti i capi di instradamento e le marche temporali.  L'opzione richiede
+  per \param{optval} un intero usato come valore logico.  L'opzione non è
+  supportata per socket di tipo \const{SOCK\_STREAM}.
+
+\item[\constd{IP\_ROUTER\_ALERT}] Questa è una opzione introdotta con i
+  kernel della serie 2.2.x, ed è specifica di Linux. Prende per
+  \param{optval} un intero usato come valore logico. Se abilitata
+  passa tutti i pacchetti con l'opzione \textit{IP Router Alert} (vedi
+  sez.~\ref{sec:IP_options}) che devono essere inoltrati al socket
+  corrente. Può essere usata soltanto per socket di tipo raw.
+
+\item[\constd{IP\_TOS}] L'opzione consente di leggere o impostare il campo
+  \textit{Type of Service} dell'intestazione IP (per una trattazione più
+  dettagliata, che riporta anche i valori possibili e le relative costanti di
+  definizione si veda sez.~\ref{sec:IP_header}) che permette di indicare le
+  priorità dei pacchetti. Se impostato il valore verrà mantenuto per tutti i
+  pacchetti del socket; alcuni valori (quelli che aumentano la priorità)
+  richiedono i privilegi di amministrazione con la \textit{capability}
+  \const{CAP\_NET\_ADMIN}.
+
+  Il campo TOS è di 8 bit e l'opzione richiede per \param{optval} un intero
+  che ne contenga il valore. Sono definite anche alcune costanti che
+  definiscono alcuni valori standardizzati per il \textit{Type of Service},
+  riportate in tab.~\ref{tab:IP_TOS_values}, il valore di default usato da
+  Linux è \const{IPTOS\_LOWDELAY}, ma esso può essere modificato con le
+  funzionalità del cosiddetto \textit{Advanced Routing}. Si ricordi che la
+  priorità dei pacchetti può essere impostata anche in maniera indipendente
+  dal protocollo utilizzando l'opzione \const{SO\_PRIORITY} illustrata in
+  sez.~\ref{sec:sock_generic_options}.
+
+\item[\constd{IP\_TTL}] L'opzione consente di leggere o impostare per tutti i
+  pacchetti associati al socket il campo \textit{Time to Live}
+  dell'intestazione IP che indica il numero massimo di \textit{hop} (passaggi
+  da un router ad un altro) restanti al paccheto (per una trattazione più
+  estesa si veda sez.~\ref{sec:IP_header}).  Il campo TTL è di 8 bit e
+  l'opzione richiede che \param{optval} sia un intero, che ne conterrà il
+  valore.
+\end{basedescript}
+
+
+
+\subsection{Le opzioni per i protocolli TCP e UDP}
+\label{sec:sock_tcp_udp_options}
+
+In questa sezione tratteremo le varie opzioni disponibili per i socket che
+usano i due principali protocolli di comunicazione del livello di trasporto;
+UDP e TCP.\footnote{come per le precedenti, una descrizione di queste opzioni
+  è disponibile nella settima sezione delle pagine di manuale, che si può
+  consultare rispettivamente con \texttt{man 7 tcp} e \texttt{man 7 udp}; le
+  pagine di manuale però, alla stesura di questa sezione (Agosto 2006) sono
+  alquanto incomplete.}  Dato che questi due protocolli sono entrambi
+trasportati su IP,\footnote{qui si sottintende IPv4, ma le opzioni per TCP e
+  UDP sono le stesse anche quando si usa IPv6.} oltre alle opzioni generiche
+di sez.~\ref{sec:sock_generic_options} saranno comunque disponibili anche le
+precedenti opzioni di sez.~\ref{sec:sock_ipv4_options}.\footnote{in realtà in
+  sez.~\ref{sec:sock_ipv4_options} si sono riportate le opzioni per IPv4, al
+  solito, qualora si stesse utilizzando IPv6, si potrebbero utilizzare le
+  opzioni di quest'ultimo.}
+
+Il protocollo che supporta il maggior numero di opzioni è TCP; per poterle
+utilizzare occorre specificare \const{SOL\_TCP} (o l'equivalente
+\constd{IPPROTO\_TCP}) come valore per l'argomento \param{level}. Si sono
+riportate le varie opzioni disponibili in tab.~\ref{tab:sock_opt_tcplevel},
+dove sono elencate le rispettive costanti da utilizzare come valore per
+l'argomento \param{optname}. Dette costanti e tutte le altre costanti e
+strutture collegate all'uso delle opzioni TCP sono definite in
+\headfiled{netinet/tcp.h}, ed accessibili includendo detto file.\footnote{in
+  realtà questo è il file usato dalle librerie; la definizione delle opzioni
+  effettivamente supportate da Linux si trova nel file
+  \texttt{include/linux/tcp.h} dei sorgenti del kernel, dal quale si sono
+  estratte le costanti di tab.~\ref{tab:sock_opt_tcplevel}.}
+
+\begin{table}[!htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|c|c|c|l|l|}
+    \hline
+    \textbf{Opzione}&\texttt{get}&\texttt{set}&\textbf{flag}&\textbf{Tipo}&
+                    \textbf{Descrizione}\\
+    \hline
+    \hline
+    \const{TCP\_NODELAY}      &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
+      Spedisce immediatamente i dati in segmenti singoli.\\
+    \const{TCP\_MAXSEG}       &$\bullet$&$\bullet$&         &\texttt{int}&
+      Valore della MSS per i segmenti in uscita.\\  
+    \const{TCP\_CORK}         &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+      Accumula i dati in un unico segmento.\\
+    \const{TCP\_KEEPIDLE}     &$\bullet$&$\bullet$&         &\texttt{int}& 
+      Tempo in secondi prima di inviare un \textit{keepalive}.\\
+    \const{TCP\_KEEPINTVL}    &$\bullet$&$\bullet$&         &\texttt{int}&
+      Tempo in secondi prima fra \textit{keepalive} successivi.\\
+    \const{TCP\_KEEPCNT}      &$\bullet$&$\bullet$&         &\texttt{int}& 
+      Numero massimo di \textit{keepalive} inviati.\\
+    \const{TCP\_SYNCNT}       &$\bullet$&$\bullet$&         &\texttt{int}& 
+      Numero massimo di ritrasmissioni di un SYN.\\
+    \const{TCP\_LINGER2}      &$\bullet$&$\bullet$&         &\texttt{int}&
+      Tempo di vita in stato \texttt{FIN\_WAIT2}.\\
+    \const{TCP\_DEFER\_ACCEPT}&$\bullet$&$\bullet$&         &\texttt{int}&
+      Ritorna da \func{accept} solo in presenza di dati.\\
+    \const{TCP\_WINDOW\_CLAMP}&$\bullet$&$\bullet$&         &\texttt{int}&
+      Valore della \textit{advertised window}.\\
+    \const{TCP\_INFO}         &$\bullet$&        &       &\struct{tcp\_info}& 
+      Restituisce informazioni sul socket.\\
+    \const{TCP\_QUICKACK}     &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+      Abilita la modalità \textit{quickack}.\\
+    \const{TCP\_CONGESTION}   &$\bullet$&$\bullet$&         &\texttt{char *}&
+      Imposta l'algoritmo per il controllo della congestione.\\
+   \hline
+  \end{tabular}
+  \caption{Le opzioni per i socket TCP disponibili al livello
+    \const{SOL\_TCP}.}
+  \label{tab:sock_opt_tcplevel}
+\end{table}
+
+Le descrizioni delle varie opzioni riportate in
+tab.~\ref{tab:sock_opt_tcplevel} sono estremamente sintetiche ed indicative,
+la spiegazione del funzionamento delle singole opzioni con una maggiore
+quantità di dettagli è fornita nel seguente elenco:
+\begin{basedescript}{\desclabelwidth{1.5cm}\desclabelstyle{\nextlinelabel}}
+
+\item[\constd{TCP\_NODELAY}] il protocollo TCP utilizza un meccanismo di
+  bufferizzazione dei dati uscenti, per evitare la trasmissione di tanti
+  piccoli segmenti con un utilizzo non ottimale della banda
+  disponibile.\footnote{il problema è chiamato anche
+    \itindex{silly~window~syndrome} \textit{silly window syndrome}, per averne
+    un'idea si pensi al risultato che si ottiene quando un programma di
+    terminale invia un segmento TCP per ogni tasto premuto, 40 byte di
+    intestazione di protocollo con 1 byte di dati trasmessi; per evitare
+    situazioni del genere è stato introdotto \index{algoritmo~di~Nagle}
+    l'\textsl{algoritmo di Nagle}.}  Questo meccanismo è controllato da un
+  apposito algoritmo (detto \textsl{algoritmo di Nagle}, vedi
+  sez.~\ref{sec:tcp_protocol_xxx}).  Il comportamento normale del protocollo
+  prevede che i dati siano accumulati fintanto che non si raggiunge una
+  quantità considerata adeguata per eseguire la trasmissione di un singolo
+  segmento.
+
+  Ci sono però delle situazioni in cui questo comportamento può non essere
+  desiderabile, ad esempio quando si sa in anticipo che l'applicazione invierà
+  soltanto un piccolo quantitativo di dati;\footnote{è il caso classico di una
+    richiesta HTTP.} in tal caso l'attesa introdotta dall'algoritmo di
+  bufferizzazione non soltanto è inutile, ma peggiora le prestazioni
+  introducendo un ritardo.  Impostando questa opzione si disabilita l'uso
+  dell'\textsl{algoritmo di Nagle} ed i dati vengono inviati immediatamente in
+  singoli segmenti, qualunque sia la loro dimensione.  Ovviamente l'uso di
+  questa opzione è dedicato a chi ha esigenze particolari come quella
+  illustrata, che possono essere stabilite solo per la singola applicazione.
+
+  Si tenga conto che questa opzione viene sovrascritta dall'eventuale
+  impostazione dell'opzione \const{TCP\_CORK} (il cui scopo è sostanzialmente
+  l'opposto) che blocca l'invio immediato. Tuttavia quando la si abilita viene
+  sempre forzato lo scaricamento della coda di invio (con conseguente
+  trasmissione di tutti i dati pendenti), anche qualora si fosse già abilitata
+  \const{TCP\_CORK}.\footnote{si tenga presente però che \const{TCP\_CORK} può
+    essere specificata insieme a \const{TCP\_NODELAY} soltanto a partire dal
+    kernel 2.5.71.}
+
+\item[\constd{TCP\_MAXSEG}] con questa opzione si legge o si imposta il valore
+  della MSS (\textit{Maximum Segment Size}, vedi sez.~\ref{sec:net_lim_dim} e
+  sez.~\ref{sec:tcp_protocol_xxx}) dei segmenti TCP uscenti. Se l'opzione è
+  impostata prima di stabilire la connessione, si cambia anche il valore della
+  MSS annunciata all'altro capo della connessione. Se si specificano valori
+  maggiori della MTU questi verranno ignorati, inoltre TCP imporrà anche i
+  suoi limiti massimo e minimo per questo valore.
+
+\item[\constd{TCP\_CORK}] questa opzione è il complemento naturale di
+  \const{TCP\_NODELAY} e serve a gestire a livello applicativo la situazione
+  opposta, cioè quella in cui si sa fin dal principio che si dovranno inviare
+  grosse quantità di dati. Anche in questo caso l'\textsl{algoritmo di Nagle}
+  tenderà a suddividerli in dimensioni da lui ritenute
+  opportune,\footnote{l'algoritmo cerca di tenere conto di queste situazioni,
+    ma essendo un algoritmo generico tenderà comunque ad introdurre delle
+    suddivisioni in segmenti diversi, anche quando potrebbero non essere
+    necessarie, con conseguente spreco di banda.}  ma sapendo fin dall'inizio
+  quale è la dimensione dei dati si potranno di nuovo ottenere delle migliori
+  prestazioni disabilitandolo, e gestendo direttamente l'invio del nostro
+  blocco di dati in soluzione unica.
+
+  Quando questa opzione viene abilitata non vengono inviati segmenti di dati
+  fintanto che essa non venga disabilitata; a quel punto tutti i dati rimasti
+  in coda saranno inviati in un solo segmento TCP. In sostanza con questa
+  opzione si può controllare il flusso dei dati mettendo una sorta di
+  ``\textsl{tappo}'' (da cui il nome in inglese) al flusso di uscita, in modo
+  ottimizzare a mano l'uso della banda. Si tenga presente che per l'effettivo
+  funzionamento ci si deve ricordare di disattivare l'opzione al termine
+  dell'invio del blocco dei dati.
+
+  Si usa molto spesso \const{TCP\_CORK} quando si effettua il trasferimento
+  diretto di un blocco di dati da un file ad un socket con \func{sendfile}
+  (vedi sez.~\ref{sec:file_sendfile_splice}), per inserire una intestazione
+  prima della chiamata a questa funzione; senza di essa l'intestazione
+  potrebbe venire spedita in un segmento a parte, che a seconda delle
+  condizioni potrebbe richiedere anche una risposta di ACK, portando ad una
+  notevole penalizzazione delle prestazioni.
+
+  Si tenga presente che l'implementazione corrente di \const{TCP\_CORK} non
+  consente di bloccare l'invio dei dati per più di 200 millisecondi, passati i
+  quali i dati accumulati in coda sanno inviati comunque.  Questa opzione è
+  tipica di Linux\footnote{l'opzione è stata introdotta con i kernel della
+    serie 2.4.x.} e non è disponibile su tutti i kernel unix-like, pertanto
+  deve essere evitata se si vuole scrivere codice portabile.
+
+\item[\constd{TCP\_KEEPIDLE}] con questa opzione si legge o si imposta
+  l'intervallo di tempo, in secondi, che deve trascorrere senza traffico sul
+  socket prima che vengano inviati, qualora si sia attivata su di esso
+  l'opzione \const{SO\_KEEPALIVE}, i messaggi di \textit{keep-alive} (si veda
+  la trattazione relativa al \textit{keep-alive} in
+  sez.~\ref{sec:sock_options_main}).  Anche questa opzione non è disponibile
+  su tutti i kernel unix-like e deve essere evitata se si vuole scrivere
+  codice portabile.
+
+\item[\constd{TCP\_KEEPINTVL}] con questa opzione si legge o si imposta
+  l'intervallo di tempo, in secondi, fra due messaggi di \textit{keep-alive}
+  successivi (si veda sempre quanto illustrato in
+  sez.~\ref{sec:sock_options_main}). Come la precedente non è disponibile su
+  tutti i kernel unix-like e deve essere evitata se si vuole scrivere codice
+  portabile.
+
+\item[\constd{TCP\_KEEPCNT}] con questa opzione si legge o si imposta il numero
+  totale di messaggi di \textit{keep-alive} da inviare prima di concludere che
+  la connessione è caduta per assenza di risposte ad un messaggio di
+  \textit{keep-alive} (di nuovo vedi sez.~\ref{sec:sock_options_main}). Come
+  la precedente non è disponibile su tutti i kernel unix-like e deve essere
+  evitata se si vuole scrivere codice portabile.
+
+\item[\constd{TCP\_SYNCNT}] con questa opzione si legge o si imposta il numero
+  di tentativi di ritrasmissione dei segmenti SYN usati nel \textit{three way
+    handshake} prima che il tentativo di connessione venga abortito (si
+  ricordi quanto accennato in sez.~\ref{sec:TCP_func_connect}). Sovrascrive
+  per il singolo socket il valore globale impostato con la \textit{sysctl}
+  \texttt{tcp\_syn\_retries} (vedi sez.~\ref{sec:sock_ipv4_sysctl}).  Non
+  vengono accettati valori maggiori di 255; anche questa opzione non è
+  standard e deve essere evitata se si vuole scrivere codice portabile.
+
+\item[\constd{TCP\_LINGER2}] con questa opzione si legge o si imposta, in
+  numero di secondi, il tempo di sussistenza dei socket terminati nello stato
+  \texttt{FIN\_WAIT2} (si ricordi quanto visto in
+  sez.~\ref{sec:TCP_conn_term}).\footnote{si tenga ben presente che questa
+    opzione non ha nulla a che fare con l'opzione \const{SO\_LINGER} che
+    abbiamo visto in sez.~\ref{sec:sock_options_main}.}  Questa opzione
+  consente di sovrascrivere per il singolo socket il valore globale impostato
+  con la \textit{sysctl} \texttt{tcp\_fin\_timeout} (vedi
+  sez.~\ref{sec:sock_ipv4_sysctl}).  Anche questa opzione è da evitare se si
+  ha a cuore la portabilità del codice.
+
+\item[\constd{TCP\_DEFER\_ACCEPT}] questa opzione consente di modificare il
+  comportamento standard del protocollo TCP nello stabilirsi di una
+  connessione; se ricordiamo il meccanismo del \textit{three way handshake}
+  illustrato in fig.~\ref{fig:TCP_TWH} possiamo vedere che in genere un client
+  inizierà ad inviare i dati ad un server solo dopo l'emissione dell'ultimo
+  segmento di ACK.
+
+  Di nuovo esistono situazioni (e la più tipica è quella di una richiesta
+  HTTP) in cui sarebbe utile inviare immediatamente la richiesta all'interno
+  del segmento con l'ultimo ACK del \textit{three way handshake}; si potrebbe
+  così risparmiare l'invio di un segmento successivo per la richiesta e il
+  ritardo sul server fra la ricezione dell'ACK e quello della richiesta.
+
+  Se si invoca \const{TCP\_DEFER\_ACCEPT} su un socket dal lato client (cioè
+  dal lato da cui si invoca \func{connect}) si istruisce il kernel a non
+  inviare immediatamente l'ACK finale del \textit{three way handshake},
+  attendendo per un po' di tempo la prima scrittura, in modo da inviare i dati
+  di questa insieme col segmento ACK.  Chiaramente la correttezza di questo
+  comportamento dipende in maniera diretta dal tipo di applicazione che usa il
+  socket; con HTTP, che invia una breve richiesta, permette di risparmiare un
+  segmento, con FTP, in cui invece si attende la ricezione del prompt del
+  server, introduce un inutile ritardo.
+
+  Allo stesso tempo il protocollo TCP prevede che sul lato del server la
+  funzione \func{accept} ritorni dopo la ricezione dell'ACK finale, in tal
+  caso quello che si fa usualmente è lanciare un nuovo processo per leggere i
+  successivi dati, che si bloccherà su una \func{read} se questi non sono
+  disponibili; in questo modo si saranno impiegate delle risorse (per la
+  creazione del nuovo processo) che non vengono usate immediatamente.  L'uso
+  di \const{TCP\_DEFER\_ACCEPT} consente di intervenire anche in questa
+  situazione; quando la si invoca sul lato server (vale a dire su un socket in
+  ascolto) l'opzione fa sì che \func{accept} ritorni soltanto quando sono
+  presenti dei dati sul socket, e non alla ricezione dell'ACK conclusivo del
+  \textit{three way handshake}.
+
+  L'opzione prende un valore intero che indica il numero massimo di secondi
+  per cui mantenere il ritardo, sia per quanto riguarda il ritorno di
+  \func{accept} su un server, che per l'invio dell'ACK finale insieme ai dati
+  su un client. L'opzione è specifica di Linux non deve essere utilizzata in
+  codice che vuole essere portabile.\footnote{su FreeBSD è presente una
+    opzione \texttt{SO\_ACCEPTFILTER} che consente di ottenere lo stesso
+    comportamento di \const{TCP\_DEFER\_ACCEPT} per quanto riguarda il lato
+    server.}
+
+\item[\constd{TCP\_WINDOW\_CLAMP}] con questa opzione si legge o si imposta
+  alla dimensione specificata, in byte, il valore dichiarato della
+  \textit{advertised window} (vedi sez.~\ref{sec:tcp_protocol_xxx}). Il kernel
+  impone comunque una dimensione minima pari a \texttt{SOCK\_MIN\_RCVBUF/2}.
+  Questa opzione non deve essere utilizzata in codice che vuole essere
+  portabile.
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{0.80\textwidth}
+    \includestruct{listati/tcp_info.h}
+  \end{minipage}
+  \caption{La struttura \structd{tcp\_info} contenente le informazioni sul
+    socket restituita dall'opzione \const{TCP\_INFO}.}
+  \label{fig:tcp_info_struct}
+\end{figure}
+
+\item[\constd{TCP\_INFO}] questa opzione, specifica di Linux, ma introdotta
+  anche in altri kernel (ad esempio FreeBSD) permette di controllare lo stato
+  interno di un socket TCP direttamente da un programma in \textit{user space}.
+  L'opzione restituisce in una speciale struttura \struct{tcp\_info}, la cui
+  definizione è riportata in fig.~\ref{fig:tcp_info_struct}, tutta una serie
+  di dati che il kernel mantiene, relativi al socket.  Anche questa opzione
+  deve essere evitata se si vuole scrivere codice portabile.
+
+  Con questa opzione diventa possibile ricevere una serie di informazioni
+  relative ad un socket TCP così da poter effettuare dei controlli senza dover
+  passare attraverso delle operazioni di lettura. Ad esempio si può verificare
+  se un socket è stato chiuso usando una funzione analoga a quella illustrata
+  in fig.~\ref{fig:is_closing}, in cui si utilizza il valore del campo
+  \var{tcpi\_state} di \struct{tcp\_info} per controllare lo stato del socket.
+
+\begin{figure}[!htbp]
+  \footnotesize \centering
+  \begin{minipage}[c]{\codesamplewidth}
+    \includecodesample{listati/is_closing.c}
+  \end{minipage}
+  \caption{Codice della funzione \texttt{is\_closing.c}, che controlla lo stato
+    di un socket TCP per verificare se si sta chiudendo.}
+  \label{fig:is_closing}
+\end{figure}
+
+%Si noti come nell'esempio si sia (
+
+
+\item[\constd{TCP\_QUICKACK}] con questa opzione è possibile eseguire una forma
+  di controllo sull'invio dei segmenti ACK all'interno di in flusso di dati su
+  TCP. In genere questo invio viene gestito direttamente dal kernel, il
+  comportamento standard, corrispondente la valore logico di vero (in genere
+  1) per questa opzione, è quello di inviare immediatamente i segmenti ACK, in
+  quanto normalmente questo significa che si è ricevuto un blocco di dati e si
+  può passare all'elaborazione del blocco successivo.
+
+  Qualora però la nostra applicazione sappia in anticipo che alla ricezione di
+  un blocco di dati seguirà immediatamente l'invio di un altro
+  blocco,\footnote{caso tipico ad esempio delle risposte alle richieste HTTP.}
+  poter accorpare quest'ultimo al segmento ACK permette di risparmiare sia in
+  termini di dati inviati che di velocità di risposta. Per far questo si può
+  utilizzare \const{TCP\_QUICKACK} impostando un valore logico falso (cioè 0),
+  in questo modo il kernel attenderà così da inviare il prossimo segmento di
+  ACK insieme ai primi dati disponibili.
+
+  Si tenga presente che l'opzione non è permanente, vale a dire che una volta
+  che la si sia impostata a 0 il kernel la riporterà al valore di default dopo
+  il suo primo utilizzo. Sul lato server la si può impostare anche una volta
+  sola su un socket in ascolto, ed essa verrà ereditata da tutti i socket che
+  si otterranno da esso al ritorno di \func{accept}.
+
+% TODO trattare con gli esempi di apache
+
+\item[\constd{TCP\_CONGESTION}] questa opzione permette di impostare quale
+  algoritmo per il controllo della congestione\footnote{il controllo della
+    congestione è un meccanismo previsto dal protocollo TCP (vedi
+    sez.~\ref{sec:tcp_protocol_xxx}) per evitare di trasmettere inutilmente
+    dati quando una connessione è congestionata; un buon algoritmo è
+    fondamentale per il funzionamento del protocollo, dato che i pacchetti
+    persi andrebbero ritrasmessi, per cui inviare un pacchetto su una linea
+    congestionata potrebbe causare facilmente un peggioramento della
+    situazione.} utilizzare per il singolo socket. L'opzione è stata
+  introdotta con il kernel 2.6.13,\footnote{alla data di stesura di queste
+    note (Set. 2006) è pure scarsamente documentata, tanto che non è neanche
+    definita nelle intestazioni della \acr{glibc} per cui occorre definirla a
+    mano al suo valore che è 13.} e prende come per \param{optval} il
+  puntatore ad un buffer contenente il nome dell'algoritmo di controllo che
+  si vuole usare. 
+
+  L'uso di un nome anziché di un valore numerico è dovuto al fatto che gli
+  algoritmi di controllo della congestione sono realizzati attraverso
+  altrettanti moduli del kernel, e possono pertanto essere attivati a
+  richiesta; il nome consente di caricare il rispettivo modulo e di introdurre
+  moduli aggiuntivi che implementino altri meccanismi. 
+
+  Per poter disporre di questa funzionalità occorre aver compilato il kernel
+  attivando l'opzione di configurazione generale
+  \texttt{TCP\_CONG\_ADVANCED},\footnote{disponibile come \textit{TCP:
+      advanced congestion control} nel menù \textit{Network->Networking
+      options}, che a sua volta renderà disponibile un ulteriore menù con gli
+    algoritmi presenti.} e poi abilitare i singoli moduli voluti con le varie
+  \texttt{TCP\_CONG\_*} presenti per i vari algoritmi disponibili; un elenco
+  di quelli attualmente supportati nella versione ufficiale del kernel è
+  riportato in tab.~\ref{tab:sock_tcp_congestion_algo}.\footnote{la lista è
+    presa dalla versione 2.6.17.}
+
+
+  Si tenga presente che prima della implementazione modulare alcuni di questi
+  algoritmi erano disponibili soltanto come caratteristiche generali del
+  sistema, attivabili per tutti i socket, questo è ancora possibile con la
+  \textit{sysctl} \texttt{tcp\_congestion\_control} (vedi
+  sez.~\ref{sec:sock_ipv4_sysctl}) che ha sostituito le precedenti
+  \textit{sysctl}.\footnote{riportate anche, alla data di stesura di queste
+    pagine (Set. 2006) nelle pagine di manuale, ma non più presenti.}
+
+  \begin{table}[!htb]
+    \centering
+    \footnotesize
+    \begin{tabular}[c]{|l|l|l|}
+      \hline
+      \textbf{Nome}&\textbf{Configurazione}&\textbf{Riferimento} \\
+      \hline
+      \hline
+      reno& -- &Algoritmo tradizionale, usato in caso di assenza degli altri.\\
+      \texttt{bic}     &\texttt{TCP\_CONG\_BIC}     & 
+      \url{http://www.csc.ncsu.edu/faculty/rhee/export/bitcp/index.htm}.\\
+      \texttt{cubic}   &\texttt{TCP\_CONG\_CUBIC}     & 
+      \url{http://www.csc.ncsu.edu/faculty/rhee/export/bitcp/index.htm}.\\
+      \texttt{highspeed}&\texttt{TCP\_CONG\_HSTCP}  & 
+      \url{http://www.icir.org/floyd/hstcp.html}.\\
+      \texttt{htcp}    &\texttt{TCP\_CONG\_HTCP}    & 
+      \url{http://www.hamilton.ie/net/htcp/}.\\
+      \texttt{hybla}   &\texttt{TCP\_CONG\_HYBLA}   &       
+      \url{http://www.danielinux.net/projects.html}.\\
+      \texttt{scalable}&\texttt{TCP\_CONG\_SCALABLE}&  
+      \url{http://www.deneholme.net/tom/scalable/}.\\
+      \texttt{vegas}   &\texttt{TCP\_CONG\_VEGAS}   &  
+      \url{http://www.cs.arizona.edu/protocols/}.\\
+      \texttt{westwood}&\texttt{TCP\_CONG\_WESTWOOD}& 
+      \url{http://www.cs.ucla.edu/NRL/hpi/tcpw/}.\\
+%      \texttt{}&\texttt{}& .\\
+      \hline
+    \end{tabular}
+    \caption{Gli algoritmi per il controllo della congestione disponibili con
+      Linux con le relative opzioni di configurazione da attivare.}  
+    \label{tab:sock_tcp_congestion_algo}
+  \end{table}
+
+\end{basedescript}
+
+
+Il protocollo UDP, anche per la sua maggiore semplicità, supporta un numero
+ridotto di opzioni, riportate in tab.~\ref{tab:sock_opt_udplevel}; anche in
+questo caso per poterle utilizzare occorrerà impostare l'opportuno valore per
+l'argomento \param{level}, che è \const{SOL\_UDP} (o l'equivalente
+\constd{IPPROTO\_UDP}).  Le costanti che identificano dette opzioni sono
+definite in \headfiled{netinet/udp.h}, ed accessibili includendo detto
+file.\footnote{come per TCP, la definizione delle opzioni effettivamente
+  supportate dal kernel si trova in realtà nel file
+  \texttt{include/linux/udp.h}, dal quale si sono estratte le costanti di
+  tab.~\ref{tab:sock_opt_udplevel}.}
+
+\begin{table}[!htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|c|c|c|l|l|}
+    \hline
+    \textbf{Opzione}&\texttt{get}&\texttt{set}&\textbf{flag}&\textbf{Tipo}&
+                    \textbf{Descrizione}\\
+    \hline
+    \hline
+    \constd{UDP\_CORK}  &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& %??? 
+      Accumula tutti i dati su un unico pacchetto.\\
+    \constd{UDP\_ENCAP} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& %??? 
+      Non documentata.\\
+   \hline
+  \end{tabular}
+  \caption{Le opzioni per i socket UDP disponibili al livello
+    \const{SOL\_UDP}.}
+  \label{tab:sock_opt_udplevel}
+\end{table}
+
+% TODO documentare \const{UDP\_ENCAP} 
+
+Ancora una volta le descrizioni contenute tab.~\ref{tab:sock_opt_udplevel}
+sono un semplice riferimento, una maggiore quantità di dettagli sulle
+caratteristiche delle opzioni citate è quello dell'elenco seguente:
+\begin{basedescript}{\desclabelwidth{1.5cm}\desclabelstyle{\nextlinelabel}}
+
+\item[\constd{UDP\_CORK}] questa opzione ha l'identico effetto dell'analoga
+  \const{TCP\_CORK} vista in precedenza per il protocollo TCP, e quando
+  abilitata consente di accumulare i dati in uscita su un solo pacchetto che
+  verrà inviato una volta che la si disabiliti. L'opzione è stata introdotta
+  con il kernel 2.5.44, e non deve essere utilizzata in codice che vuole
+  essere portabile.
+
+\item[\constd{UDP\_ENCAP}] Questa opzione permette di gestire l'incapsulazione
+  dei dati nel protocollo UDP. L'opzione è stata introdotta con il kernel
+  2.5.67, e non è documentata. Come la precedente è specifica di Linux e non
+  deve essere utilizzata in codice portabile.
+
+\end{basedescript}
+
+
+
+
+\section{La gestione attraverso le funzioni di controllo}
+\label{sec:sock_ctrl_func}
+
+Benché la maggior parte delle caratteristiche dei socket sia gestibile con le
+funzioni \func{setsockopt} e \func{getsockopt}, alcune proprietà possono
+essere impostate attraverso le funzioni \func{fcntl} e \func{ioctl} già
+trattate in sez.~\ref{sec:file_fcntl_ioctl}; in quell'occasione abbiamo
+parlato di queste funzioni esclusivamente nell'ambito della loro applicazione
+a file descriptor associati a dei file normali; qui tratteremo invece i
+dettagli del loro utilizzo con file descriptor associati a dei socket.
+
+
+\subsection{L'uso di \func{ioctl} e \func{fcntl} per i socket generici}
+\label{sec:sock_ioctl}
+
+Tratteremo in questa sezione le caratteristiche specifiche delle funzioni
+\func{ioctl} e \func{fcntl} quando esse vengono utilizzate con dei socket
+generici. Quanto già detto in precedenza sez.~\ref{sec:file_fcntl_ioctl}
+continua a valere; quello che tratteremo qui sono le operazioni ed i comandi
+che sono validi, o che hanno significati peculiari, quando queste funzioni
+vengono applicate a dei socket generici.
+
+Nell'elenco seguente si riportano i valori specifici che può assumere il
+secondo argomento della funzione \func{ioctl} (\param{request}, che indica il
+tipo di operazione da effettuare) quando essa viene applicata ad un socket
+generico. Nell'elenco si illustrerà anche, per ciascuna operazione, il tipo di
+dato usato come terzo argomento della funzione ed il significato che esso
+viene ad assumere.  Dato che in caso di lettura questi dati vengono restituiti
+come \textit{value result argument}, con queste operazioni il terzo argomento
+deve sempre essere passato come puntatore ad una variabile (o struttura)
+precedentemente allocata. Le costanti che identificano le operazioni sono le
+seguenti:
+\begin{basedescript}{\desclabelwidth{1.5cm}\desclabelstyle{\nextlinelabel}}
+\item[\constd{SIOCGSTAMP}] restituisce il contenuto di una struttura
+  \struct{timeval} con la marca temporale dell'ultimo pacchetto ricevuto sul
+  socket, questa operazione può essere utilizzata per effettuare delle
+  misurazioni precise del tempo di andata e ritorno\footnote{il \textit{Round
+      Trip Time} cui abbiamo già accennato in sez.~\ref{sec:net_tcp}.} dei
+  pacchetti sulla rete.
+
+\item[\constd{SIOCSPGRP}] imposta il processo o il \textit{process group} a
+  cui inviare i segnali \signal{SIGIO} e \signal{SIGURG} quando viene
+  completata una operazione di I/O asincrono o arrivano dei dati urgenti
+  (\texttt{out-of-band}). Il terzo argomento deve essere un puntatore ad una
+  variabile di tipo \type{pid\_t}; un valore positivo indica direttamente il
+  \ids{PID} del processo, mentre un valore negativo indica (col valore
+  assoluto) il \textit{process group}. Senza privilegi di amministratore o la
+  \textit{capability} \const{CAP\_KILL} si può impostare solo se stessi o il
+  proprio \textit{process group}.
+
+\item[\constd{SIOCGPGRP}] legge le impostazioni presenti sul socket
+  relativamente all'eventuale processo o \textit{process group} cui devono
+  essere inviati i segnali \signal{SIGIO} e \signal{SIGURG}. Come per
+  \const{SIOCSPGRP} l'argomento passato deve un puntatore ad una variabile di
+  tipo \type{pid\_t}, con lo stesso significato.  Qualora non sia presente
+  nessuna impostazione verrà restituito un valore nullo.
+
+\item[\const{FIOASYNC}] Abilita o disabilita la modalità di I/O asincrono sul
+  socket. Questo significa (vedi sez.~\ref{sec:signal_driven_io}) che verrà
+  inviato il segnale di \signal{SIGIO} (o quanto impostato con
+  \const{F\_SETSIG}, vedi sez.~\ref{sec:file_fcntl_ioctl}) in caso di eventi
+  di I/O sul socket.
+\end{basedescript}
+
+Nel caso dei socket generici anche \func{fcntl} prevede un paio di comandi
+specifici; in questo caso il secondo argomento (\param{cmd}, che indica il
+comando) può assumere i due valori \const{FIOGETOWN} e \const{FIOSETOWN},
+mentre il terzo argomento dovrà essere un puntatore ad una variabile di tipo
+\type{pid\_t}. Questi due comandi sono una modalità alternativa di eseguire le
+stesse operazioni (lettura o impostazione del processo o del gruppo di
+processo che riceve i segnali) che si effettuano chiamando \func{ioctl} con
+\const{SIOCGPGRP} e \const{SIOCSPGRP}.
+
+
+\subsection{L'uso di \func{ioctl} per l'accesso ai dispositivi di rete}
+\label{sec:sock_ioctl_netdevice}
+
+Benché non strettamente attinenti alla gestione dei socket, vale la pena di
+trattare qui l'interfaccia di accesso a basso livello ai dispositivi di rete
+che viene appunto fornita attraverso la funzione \texttt{ioctl}. Questa non è
+attinente a caratteristiche specifiche di un qualche protocollo, ma si applica
+a tutti i socket, indipendentemente da tipo e famiglia degli stessi, e
+permette di impostare e rilevare le funzionalità delle interfacce di rete.
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{0.80\textwidth}
+    \includestruct{listati/ifreq.h}
+  \end{minipage}
+  \caption{La struttura \structd{ifreq} utilizzata dalle \func{ioctl} per le
+    operazioni di controllo sui dispositivi di rete.}
+  \label{fig:netdevice_ifreq_struct}
+\end{figure}
+
+Tutte le operazioni di questo tipo utilizzano come terzo argomento di
+\func{ioctl} il puntatore ad una struttura \struct{ifreq}, la cui definizione
+è illustrata in fig.~\ref{fig:netdevice_ifreq_struct}. Normalmente si utilizza
+il primo campo della struttura, \var{ifr\_name} per specificare il nome
+dell'interfaccia su cui si vuole operare (ad esempio \texttt{eth0},
+\texttt{ppp0}, ecc.), e si inseriscono (o ricevono) i valori relativi alle
+diversa caratteristiche e funzionalità nel secondo campo, che come si può
+notare è definito come una \dirct{union} proprio in quanto il suo significato
+varia a secondo dell'operazione scelta.
+
+Si tenga inoltre presente che alcune di queste operazioni (in particolare
+quelle che modificano le caratteristiche dell'interfaccia) sono privilegiate e
+richiedono i privilegi di amministratore o la \textit{capability}
+\const{CAP\_NET\_ADMIN}, altrimenti si otterrà un errore di \errval{EPERM}.
+Le costanti che identificano le operazioni disponibili sono le seguenti:
+\begin{basedescript}{\desclabelwidth{1.5cm}\desclabelstyle{\nextlinelabel}}
+\item[\constd{SIOCGIFNAME}] questa è l'unica operazione che usa il campo
+  \var{ifr\_name} per restituire un risultato, tutte le altre lo utilizzano
+  per indicare l'interfaccia sulla quale operare. L'operazione richiede che si
+  indichi nel campo \var{ifr\_ifindex} il valore numerico dell'\textsl{indice}
+  dell'interfaccia, e restituisce il relativo nome in \var{ifr\_name}.
+
+  Il kernel infatti assegna ad ogni interfaccia un numero progressivo, detto
+  appunto \itindex{interface~index} \textit{interface index}, che è quello che
+  effettivamente la identifica nelle operazioni a basso livello, il nome
+  dell'interfaccia è soltanto una etichetta associata a detto \textsl{indice},
+  che permette di rendere più comprensibile l'indicazione dell'interfaccia
+  all'interno dei comandi. Una modalità per ottenere questo valore è usare il
+  comando \cmd{ip link}, che fornisce un elenco delle interfacce presenti
+  ordinato in base a tale valore (riportato come primo campo).
+  
+
+\item[\constd{SIOCGIFINDEX}] restituisce nel campo \var{ifr\_ifindex} il valore
+  numerico dell'indice dell'interfaccia specificata con \var{ifr\_name}, è in
+  sostanza l'operazione inversa di \const{SIOCGIFNAME}.
+
+\item[\constd{SIOCGIFFLAGS}] permette di ottenere nel campo \var{ifr\_flags} il
+  valore corrente dei flag dell'interfaccia specificata (con \var{ifr\_name}).
+  Il valore restituito è una maschera binaria i cui bit sono identificabili
+  attraverso le varie costanti di tab.~\ref{tab:netdevice_iface_flag}.
+
+\begin{table}[htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|p{8cm}|}
+    \hline
+    \textbf{Flag} & \textbf{Significato} \\
+    \hline
+    \hline
+    \constd{IFF\_UP}        & L'interfaccia è attiva.\\
+    \constd{IFF\_BROADCAST} & L'interfaccia ha impostato un indirizzo di
+                             \textit{broadcast} valido.\\
+    \constd{IFF\_DEBUG}     & È attivo il flag interno di debug.\\
+    \constd{IFF\_LOOPBACK}  & L'interfaccia è una interfaccia di
+                             \textit{loopback}.\\ 
+    \constd{IFF\_POINTOPOINT}&L'interfaccia è associata ad un collegamento
+                             \textsl{punto-punto}.\\ 
+    \constd{IFF\_RUNNING}   & L'interfaccia ha delle risorse allocate (non può
+                             quindi essere disattivata).\\
+    \constd{IFF\_NOARP}     & L'interfaccia ha il protocollo ARP disabilitato o
+                             l'indirizzo del livello di rete non è impostato.\\
+    \constd{IFF\_PROMISC}   & L'interfaccia è nel cosiddetto
+                             \index{modo~promiscuo} \textsl{modo promiscuo},
+                             riceve cioè tutti i pacchetti che vede passare,
+                             compresi quelli non direttamente indirizzati a
+                             lei.\\
+    \constd{IFF\_NOTRAILERS}& Evita l'uso di \textit{trailer} nei pacchetti.\\
+    \constd{IFF\_ALLMULTI}  & Riceve tutti i pacchetti di \textit{multicast}.\\
+    \constd{IFF\_MASTER}    & L'interfaccia è il master di un bundle per il
+                             bilanciamento di carico.\\
+    \constd{IFF\_SLAVE}     & L'interfaccia è uno slave di un bundle per il
+                             bilanciamento di carico.\\
+    \constd{IFF\_MULTICAST} & L'interfaccia ha il supporto per il
+                             \textit{multicast} attivo.\\
+    \constd{IFF\_PORTSEL}   & L'interfaccia può impostare i suoi parametri
+                             hardware (con l'uso di \struct{ifmap}).\\
+    \constd{IFF\_AUTOMEDIA} & L'interfaccia è in grado di selezionare
+                             automaticamente il tipo di collegamento.\\
+    \constd{IFF\_DYNAMIC}   & Gli indirizzi assegnati all'interfaccia vengono
+                             persi quando questa viene disattivata.\\
+%    \const{IFF\_}      & .\\
+    \hline
+  \end{tabular}
+  \caption{Le costanti che identificano i vari bit della maschera binaria
+    \var{ifr\_flags} che esprime i flag di una interfaccia di rete.}
+  \label{tab:netdevice_iface_flag}
+\end{table}
+
+
+\item[\constd{SIOCSIFFLAGS}] permette di impostare il valore dei flag
+  dell'interfaccia specificata (sempre con \var{ifr\_name}, non staremo a
+  ripeterlo oltre) attraverso il valore della maschera binaria da passare nel
+  campo \var{ifr\_flags}, che può essere ottenuta con l'OR aritmetico delle
+  costanti di tab.~\ref{tab:netdevice_iface_flag}; questa operazione è
+  privilegiata.
+
+\item[\constd{SIOCGIFMETRIC}] permette di leggere il valore della metrica del
+  dispositivo associato all'interfaccia specificata nel campo
+  \var{ifr\_metric}.  Attualmente non è implementato, e l'operazione
+  restituisce sempre un valore nullo.
+
+\item[\constd{SIOCSIFMETRIC}] permette di impostare il valore della metrica del
+  dispositivo al valore specificato nel campo \var{ifr\_metric}, attualmente
+  non ancora implementato, restituisce un errore di \errval{EOPNOTSUPP}.
+
+\item[\constd{SIOCGIFMTU}] permette di leggere il valore della \textit{Maximum
+    Transfer Unit} del dispositivo nel campo \var{ifr\_mtu}.
+
+\item[\constd{SIOCSIFMTU}] permette di impostare il valore della
+  \textit{Maximum Transfer Unit} del dispositivo al valore specificato campo
+  \var{ifr\_mtu}. L'operazione è privilegiata, e si tenga presente che
+  impostare un valore troppo basso può causare un blocco del kernel.
+
+\item[\constd{SIOCGIFHWADDR}] permette di leggere il valore dell'indirizzo
+  hardware del dispositivo associato all'interfaccia nel campo
+  \var{ifr\_hwaddr}; questo viene restituito come struttura \struct{sockaddr}
+  in cui il campo \var{sa\_family} contiene un valore \texttt{ARPHRD\_*}
+  indicante il tipo di indirizzo ed il campo \var{sa\_data} il valore binario
+  dell'indirizzo hardware a partire dal byte 0.
+
+\item[\constd{SIOCSIFHWADDR}] permette di impostare il valore dell'indirizzo
+  hardware del dispositivo associato all'interfaccia attraverso il valore
+  della struttura \struct{sockaddr} (con lo stesso formato illustrato per
+  \const{SIOCGIFHWADDR}) passata nel campo \var{ifr\_hwaddr}. L'operazione è
+  privilegiata.
+
+\item[\constd{SIOCSIFHWBROADCAST}] imposta l'indirizzo \textit{broadcast}
+  hardware dell'interfaccia al valore specificato dal campo
+  \var{ifr\_hwaddr}. L'operazione è privilegiata.
+
+\item[\constd{SIOCGIFMAP}] legge alcuni parametri hardware (memoria, interrupt,
+  canali di DMA) del driver dell'interfaccia specificata, restituendo i
+  relativi valori nel campo \var{ifr\_map}; quest'ultimo contiene una
+  struttura di tipo \struct{ifmap}, la cui definizione è illustrata in
+  fig.~\ref{fig:netdevice_ifmap_struct}.
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{0.80\textwidth}
+    \includestruct{listati/ifmap.h}
+  \end{minipage}
+  \caption{La struttura \structd{ifmap} utilizzata per leggere ed impostare i
+    valori dei parametri hardware di un driver di una interfaccia.}
+  \label{fig:netdevice_ifmap_struct}
+\end{figure}
+
+\item[\constd{SIOCSIFMAP}] imposta i parametri hardware del driver
+  dell'interfaccia specificata, restituendo i relativi valori nel campo
+  \var{ifr\_map}. Come per \const{SIOCGIFMAP} questo deve essere passato come
+  struttura \struct{ifmap}, secondo la definizione di
+  fig.~\ref{fig:netdevice_ifmap_struct}.
+
+\item[\constd{SIOCADDMULTI}] aggiunge un indirizzo di \textit{multicast} ai
+  filtri del livello di collegamento associati dell'interfaccia. Si deve usare
+  un indirizzo hardware da specificare attraverso il campo \var{ifr\_hwaddr},
+  che conterrà l'opportuna struttura \struct{sockaddr}; l'operazione è
+  privilegiata. Per una modalità alternativa per eseguire la stessa operazione
+  si possono usare i \textit{packet socket}, vedi
+  sez.~\ref{sec:packet_socket}.
+
+\item[\constd{SIOCDELMULTI}] rimuove un indirizzo di \textit{multicast} ai
+  filtri del livello di collegamento dell'interfaccia, vuole un indirizzo
+  hardware specificato come per \const{SIOCADDMULTI}. Anche questa operazione
+  è privilegiata e può essere eseguita in forma alternativa con i
+  \textit{packet socket}.
+
+\item[\constd{SIOCGIFTXQLEN}] permette di leggere la lunghezza della coda di
+  trasmissione del dispositivo associato all'interfaccia specificata nel campo
+  \var{ifr\_qlen}.
+
+\item[\constd{SIOCSIFTXQLEN}] permette di impostare il valore della lunghezza
+  della coda di trasmissione del dispositivo associato all'interfaccia, questo
+  deve essere specificato nel campo \var{ifr\_qlen}. L'operazione è
+  privilegiata. 
+
+\item[\constd{SIOCSIFNAME}] consente di cambiare il nome dell'interfaccia
+  indicata da \var{ifr\_name} utilizzando il nuovo nome specificato nel campo
+  \var{ifr\_rename}.
+
+\end{basedescript}
+
+
+% TODO aggiunta con il kernel 3.14 SIOCGHWTSTAMP per ottenere il timestamp
+% hardware senza modificarlo
+
+Una ulteriore operazione, che consente di ricavare le caratteristiche delle
+interfacce di rete, è \constd{SIOCGIFCONF}; però per ragioni di compatibilità
+questa operazione è disponibile soltanto per i socket della famiglia
+\const{AF\_INET} (vale ad dire per socket IPv4). In questo caso l'utente dovrà
+passare come argomento una struttura \struct{ifconf}, definita in
+fig.~\ref{fig:netdevice_ifconf_struct}.
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{0.80\textwidth}
+    \includestruct{listati/ifconf.h}
+  \end{minipage}
+  \caption{La struttura \structd{ifconf}.}
+  \label{fig:netdevice_ifconf_struct}
+\end{figure}
+
+Per eseguire questa operazione occorrerà allocare preventivamente un buffer di
+contenente un vettore di strutture \struct{ifreq}. La dimensione (in byte) di
+questo buffer deve essere specificata nel campo \var{ifc\_len} di
+\struct{ifconf}, mentre il suo indirizzo andrà specificato nel campo
+\var{ifc\_req}. Qualora il buffer sia stato allocato come una stringa, il suo
+indirizzo potrà essere fornito usando il campo \var{ifc\_buf}.\footnote{si
+  noti che l'indirizzo del buffer è definito in \struct{ifconf} con una
+  \dirct{union}, questo consente di utilizzare una delle due forme a piacere.}
+
+La funzione restituisce nel buffer indicato una serie di strutture
+\struct{ifreq} contenenti nel campo \var{ifr\_name} il nome dell'interfaccia e
+nel campo \var{ifr\_addr} il relativo indirizzo IP.  Se lo spazio allocato nel
+buffer è sufficiente il kernel scriverà una struttura \struct{ifreq} per
+ciascuna interfaccia attiva, restituendo nel campo \var{ifc\_len} il totale
+dei byte effettivamente scritti. Il valore di ritorno è 0 se l'operazione ha
+avuto successo e negativo in caso contrario. 
+
+Si tenga presente che il kernel non scriverà mai sul buffer di uscita dati
+eccedenti numero di byte specificato col valore di \var{ifc\_len} impostato
+alla chiamata della funzione, troncando il risultato se questi non dovessero
+essere sufficienti. Questa condizione non viene segnalata come errore per cui
+occorre controllare il valore di \var{ifc\_len} all'uscita della funzione, e
+verificare che esso sia inferiore a quello di ingresso. In caso contrario si è
+probabilmente\footnote{probabilmente perché si potrebbe essere nella
+  condizione in cui sono stati usati esattamente quel numero di byte.} avuta
+una situazione di troncamento dei dati.
+
+\begin{figure}[!htbp]
+  \footnotesize \centering
+  \begin{minipage}[c]{\codesamplewidth}
+    \includecodesample{listati/iflist.c}
+  \end{minipage}
+  \caption{Il corpo principale del programma \texttt{iflist.c}.}
+  \label{fig:netdevice_iflist}
+\end{figure}
+
+Come esempio dell'uso di queste funzioni si è riportato in
+fig.~\ref{fig:netdevice_iflist} il corpo principale del programma
+\texttt{iflist} in cui si utilizza l'operazione \const{SIOCGIFCONF} per
+ottenere una lista delle interfacce attive e dei relativi indirizzi. Al solito
+il codice completo è fornito nei sorgenti allegati alla guida.
+
+Il programma inizia (\texttt{\small 7--11}) con la creazione del socket
+necessario ad eseguire l'operazione, dopo di che si inizializzano
+opportunamente (\texttt{\small 13--14}) i valori della struttura
+\struct{ifconf} indicando la dimensione del buffer ed il suo
+indirizzo;\footnote{si noti come in questo caso si sia specificato l'indirizzo
+  usando il campo \var{ifc\_buf}, mentre nel seguito del programma si accederà
+  ai valori contenuti nel buffer usando \var{ifc\_req}.} si esegue poi
+l'operazione invocando \func{ioctl}, controllando come sempre la corretta
+esecuzione, ed uscendo in caso di errore (\texttt{\small 15--19}).
+
+Si esegue poi un controllo sulla quantità di dati restituiti segnalando un
+eventuale overflow del buffer (\texttt{\small 21--23}); se invece è tutto a
+posto (\texttt{\small 24--27}) si calcola e si stampa a video il numero di
+interfacce attive trovate.  L'ultima parte del programma (\texttt{\small
+  28--33}) è il ciclo sul contenuto delle varie strutture \struct{ifreq}
+restituite in cui si estrae (\texttt{\small 30}) l'indirizzo ad esse
+assegnato\footnote{si è definito \var{access} come puntatore ad una struttura
+  di tipo \struct{sockaddr\_in} per poter eseguire un \textit{casting}
+  dell'indirizzo del valore restituito nei vari campi \var{ifr\_addr}, così
+  poi da poterlo poi usare come argomento di \func{inet\_ntoa}.}  e lo si
+stampa (\texttt{\small 31--32}) insieme al nome dell'interfaccia.
+
+
+
+\subsection{L'uso di \func{ioctl} per i socket TCP e UDP}
+\label{sec:sock_ioctl_IP}
+
+Non esistono operazioni specifiche per i socket IP in quanto tali,\footnote{a
+  parte forse \const{SIOCGIFCONF}, che però resta attinente alle proprietà
+  delle interfacce di rete, per cui l'abbiamo trattata in
+  sez.~\ref{sec:sock_ioctl_netdevice} insieme alle altre che comunque si
+  applicano anche ai socket IP.} mentre per i pacchetti di altri protocolli
+trasportati su IP, qualora li si gestisca attraverso dei socket, si dovrà fare
+riferimento direttamente all'eventuale supporto presente per il tipo di socket
+usato: ad esempio si possono ricevere pacchetti ICMP con socket di tipo
+\texttt{raw}, nel qual caso si dovrà fare riferimento alle operazioni di
+quest'ultimo.
+
+Tuttavia la gran parte dei socket utilizzati nella programmazione di rete
+utilizza proprio il protocollo IP, e quello che succede è che in realtà la
+funzione \func{ioctl} consente di effettuare alcune operazioni specifiche per
+i socket che usano questo protocollo, ma queste vendono eseguite, invece che a
+livello di IP, al successivo livello di trasporto, vale a dire in maniera
+specifica per i socket TCP e UDP.
+
+Le operazioni di controllo disponibili per i socket TCP sono illustrate dalla
+relativa pagina di manuale, accessibile con \texttt{man 7 tcp}, e prevedono
+come possibile valore per il secondo argomento della funzione le costanti
+illustrate nell'elenco seguente; il terzo argomento della funzione, gestito
+come \textit{value result argument}, deve essere sempre il puntatore ad una
+variabile di tipo \ctyp{int}:
+\begin{basedescript}{\desclabelwidth{1.5cm}\desclabelstyle{\nextlinelabel}}
+\item[\constd{SIOCINQ}] restituisce la quantità di dati non ancora letti
+  presenti nel buffer di ricezione; il socket non deve essere in stato
+  \texttt{LISTEN}, altrimenti si avrà un errore di \errval{EINVAL}.
+\item[\constd{SIOCATMARK}] ritorna un intero non nullo, da intendere come
+  valore logico, se il flusso di dati letti sul socket è arrivato sulla
+  posizione (detta anche \textit{urgent mark}) in cui sono stati ricevuti dati
+  urgenti (vedi sez.~\ref{sec:TCP_urgent_data}).  Una operazione di lettura da
+  un socket non attraversa mai questa posizione, per cui è possibile
+  controllare se la si è raggiunta o meno con questa operazione.
+
+  Questo è utile quando si attiva l'opzione \const{SO\_OOBINLINE} (vedi
+  sez.~\ref{sec:sock_generic_options}) per ricevere i dati urgenti all'interno
+  del flusso dei dati ordinari del socket;\footnote{vedremo in
+    sez.~\ref{sec:TCP_urgent_data} che in genere i dati urgenti presenti su un
+    socket si leggono \textit{out-of-band} usando un opportuno flag per
+    \func{recvmsg}.}  in tal caso quando \const{SIOCATMARK} restituisce un
+  valore non nullo si saprà che la successiva lettura dal socket restituirà i
+  dati urgenti e non il normale traffico; torneremo su questo in maggior
+  dettaglio in sez.~\ref{sec:TCP_urgent_data}.
+
+\item[\constd{SIOCOUTQ}] restituisce la quantità di dati non ancora inviati
+  presenti nel buffer di spedizione; come per \const{SIOCINQ} il socket non
+  deve essere in stato \texttt{LISTEN}, altrimenti si avrà un errore di
+  \errval{EINVAL}.
+\end{basedescript}
+
+Le operazioni di controllo disponibili per i socket UDP, anch'esse illustrate
+dalla relativa pagina di manuale accessibile con \texttt{man 7 udp}, sono
+quelle indicate dalle costanti del seguente elenco; come per i socket TCP il
+terzo argomento viene gestito come \textit{value result argument} e deve
+essere un puntatore ad una variabile di tipo \ctyp{int}:
+\begin{basedescript}{\desclabelwidth{1.5cm}\desclabelstyle{\nextlinelabel}}
+\item[\const{FIONREAD}] restituisce la dimensione in byte del primo pacchetto
+  in attesa di ricezione, o 0 qualora non ci sia nessun pacchetto.
+\item[\const{TIOCOUTQ}] restituisce il numero di byte presenti nella coda di
+  invio locale; questa opzione è supportata soltanto a partire dal kernel 2.4
+\end{basedescript}
+
+
+
+\section{La gestione con \func{sysctl} ed il filesystem \texttt{/proc}}
+\label{sec:sock_sysctl_proc}
+
+Come ultimo argomento di questo capitolo tratteremo l'uso della funzione
+\func{sysctl} (che è stata introdotta nelle sue funzionalità generiche in
+sez.~\ref{sec:sys_sysctl}) per quanto riguarda le sue capacità di effettuare
+impostazioni relative alle proprietà dei socket.  Dato che le stesse
+funzionalità sono controllabili direttamente attraverso il filesystem
+\texttt{/proc}, le tratteremo attraverso i file presenti in quest'ultimo.
+
+
+\subsection{L'uso di \func{sysctl} e \texttt{/proc} per le proprietà della
+  rete}
+\label{sec:sock_sysctl}
+
+La differenza nell'uso di \func{sysctl} e del filesystem \texttt{/proc}
+rispetto a quello delle funzioni \func{ioctl} e \func{fcntl} visto in
+sez.~\ref{sec:sock_ctrl_func} o all'uso di \func{getsockopt} e
+\func{setsockopt} è che queste funzioni consentono di controllare le proprietà
+di un singolo socket, mentre con \func{sysctl} e con \texttt{/proc} si
+impostano proprietà (o valori di default) validi a livello dell'intero
+sistema, e cioè per tutti i socket.
+
+Le opzioni disponibili per le proprietà della rete, nella gerarchia dei valori
+impostabili con \func{sysctl}, sono riportate sotto il nodo \texttt{net}, o,
+se acceduti tramite l'interfaccia del filesystem \texttt{/proc}, sotto
+\texttt{/proc/sys/net}. In genere sotto questa directory compaiono le
+sottodirectory (corrispondenti ad altrettanti sotto-nodi per \func{sysctl})
+relative ai vari protocolli e tipi di interfacce su cui è possibile
+intervenire per effettuare impostazioni; un contenuto tipico di questa
+directory è il seguente:
+\begin{verbatim}
+/proc/sys/net/
+|-- core
+|-- ethernet
+|-- ipv4
+|-- ipv6
+|-- irda
+|-- token-ring
+`-- unix
+\end{verbatim}
+e sono presenti varie centinaia di parametri, molti dei quali non sono neanche
+documentati; nel nostro caso ci limiteremo ad illustrare quelli più
+significativi.
+
+Si tenga presente infine che se è sempre possibile utilizzare il filesystem
+\texttt{/proc} come sostituto di \func{sysctl}, dato che i valori di nodi e
+sotto-nodi di quest'ultima sono mappati come file e directory sotto
+\texttt{/proc/sys/}, non è vero il contrario, ed in particolare Linux consente
+di impostare alcuni parametri o leggere lo stato della rete a livello di
+sistema sotto \texttt{/proc/net}, dove sono presenti dei file che non
+corrispondono a nessun nodo di \func{sysctl}.
+
+
+\subsection{I valori di controllo per i socket generici}
+\label{sec:sock_gen_sysctl}
+
+Nella directory \texttt{/proc/sys/net/core/} sono presenti i file
+corrispondenti ai parametri generici di \textit{sysctl} validi per tutti i
+socket.  Quelli descritti anche nella pagina di manuale, accessibile con
+\texttt{man 7 socket} sono i seguenti:
+
+\begin{basedescript}{\desclabelwidth{2.2cm}\desclabelstyle{\nextlinelabel}}
+\item[\sysctlrelfiled{net/core}{rmem\_default}] imposta la dimensione
+  di default del buffer di ricezione (cioè per i dati in ingresso) dei socket.
+\item[\sysctlrelfiled{net/core}{rmem\_max}] imposta la dimensione
+  massima che si può assegnare al buffer di ricezione dei socket attraverso
+  l'uso dell'opzione \const{SO\_RCVBUF}.
+\item[\sysctlrelfiled{net/core}{wmem\_default}] imposta la dimensione
+  di default del buffer di trasmissione (cioè per i dati in uscita) dei
+  socket.
+\item[\sysctlrelfiled{net/core}{wmem\_max}] imposta la dimensione
+  massima che si può assegnare al buffer di trasmissione dei socket attraverso
+  l'uso dell'opzione \const{SO\_SNDBUF}.
+\item[\sysctlrelfiled{net/core}{message\_cost},
+  \sysctlrelfiled{net/core}{message\_burst}] contengono le impostazioni del
+  \textit{bucket filter} che controlla l'emissione di
+  messaggi di avviso da parte del kernel per eventi relativi a problemi sulla
+  rete, imponendo un limite che consente di prevenire eventuali attacchi di
+  \textit{Denial of Service} usando i log.\footnote{senza questo limite un
+    attaccante potrebbe inviare ad arte un traffico che generi
+    intenzionalmente messaggi di errore, per saturare il sistema dei log.}
+
+  \itindbeg{bucket~filter} 
+
+  Il \textit{bucket filter} è un algoritmo generico che permette di impostare
+  dei limiti di flusso su una quantità\footnote{uno analogo viene usato per
+    imporre dei limiti sul flusso dei pacchetti nel \textit{netfilter} di
+    Linux.}  senza dovere eseguire medie temporali, che verrebbero a dipendere
+  in misura non controllabile dalla dimensione dell'intervallo su cui si media
+  e dalla distribuzione degli eventi;\footnote{in caso di un picco di flusso
+    (il cosiddetto \textit{burst}) il flusso medio verrebbe a dipendere in
+    maniera esclusiva dalla dimensione dell'intervallo di tempo su cui calcola
+    la media.} in questo caso si definisce la dimensione di un
+  ``\textsl{bidone}'' (il \textit{bucket}) e del flusso che da esso può
+  uscire, la presenza di una dimensione iniziale consente di assorbire
+  eventuali picchi di emissione, l'aver fissato un flusso di uscita garantisce
+  che a regime questo sarà il valore medio del flusso ottenibile dal
+  \textit{bucket}.
+
+  \itindend{bucket~filter} 
+
+  I due valori indicano rispettivamente il flusso a regime (non sarà inviato
+  più di un messaggio per il numero di secondi specificato da
+  \texttt{message\_cost}) e la dimensione iniziale per in caso di picco di
+  emissione (verranno accettati inizialmente fino ad un massimo di
+  \texttt{message\_cost/message\_burst} messaggi).
+
+\item[\sysctlrelfiled{net/core}{netdev\_max\_backlog}] numero massimo
+  di pacchetti che possono essere contenuti nella coda di ingresso generale.
+
+\item[\sysctlrelfiled{net/core}{optmem\_max}] lunghezza massima dei
+  dati ancillari e di controllo (vedi sez.~\ref{sec:net_ancillary_data}).
+\end{basedescript}
+
+Oltre a questi, nella directory \texttt{/proc/sys/net/core} si trovano diversi
+altri file, la cui documentazione, come per gli altri, dovrebbe essere
+mantenuta nei sorgenti del kernel nel file
+\texttt{Documentation/networking/ip-sysctl.txt}; la maggior parte di questi
+però non è documentato:
+\begin{basedescript}{\desclabelwidth{2.2cm}\desclabelstyle{\nextlinelabel}}
+\item[\sysctlrelfiled{net/core}{dev\_weight}] blocco di lavoro (\textit{work
+    quantum}) dello \textit{scheduler} di processo dei pacchetti.
+
+% TODO da documentare meglio
+
+\item[\sysctlrelfiled{net/core}{lo\_cong}] valore per l'occupazione
+  della coda di ricezione sotto la quale si considera di avere una bassa
+  congestione.
+
+\item[\sysctlrelfiled{net/core}{mod\_cong}] valore per l'occupazione della
+  coda di ricezione sotto la quale si considera di avere una congestione
+  moderata.
+
+\item[\sysctlrelfiled{net/core}{no\_cong}] valore per l'occupazione della coda
+  di ricezione sotto la quale si considera di non avere congestione.
+
+\item[\sysctlrelfiled{net/core}{no\_cong\_thresh}] valore minimo (\textit{low
+    water mark}) per il riavvio dei dispositivi congestionati.
+
+  % \item[\sysctlrelfiled{net/core}{netdev\_fastroute}] è presente
+  %   soltanto quando si è compilato il kernel con l'apposita opzione di
+  %   ottimizzazione per l'uso come router.
+
+\item[\sysctlrelfiled{net/core}{somaxconn}] imposta la dimensione massima
+  utilizzabile per il \textit{backlog} della funzione \func{listen} (vedi
+  sez.~\ref{sec:TCP_func_listen}), e corrisponde al valore della costante
+  \constd{SOMAXCONN}; il suo valore di default è 128.
+
+\end{basedescript}
+
+
+\subsection{I valori di controllo per il protocollo IPv4}
+\label{sec:sock_ipv4_sysctl}
+
+Nella directory \texttt{/proc/sys/net/ipv4} sono presenti i file che
+corrispondono ai parametri dei socket che usano il protocollo IPv4, relativi
+quindi sia alle caratteristiche di IP, che a quelle degli altri protocolli che
+vengono usati all'interno di quest'ultimo (come ICMP, TCP e UDP) o a fianco
+dello stesso (come ARP).
+
+I file che consentono di controllare le caratteristiche specifiche del
+protocollo IP in quanto tale, che sono descritti anche nella relativa pagina
+di manuale accessibile con \texttt{man 7 ip}, sono i seguenti:
+\begin{basedescript}{\desclabelwidth{2.2cm}\desclabelstyle{\nextlinelabel}}
+
+\item[\sysctlrelfiled{net/ipv4}{ip\_default\_ttl}] imposta il valore di
+  default per il campo TTL (vedi sez.~\ref{sec:IP_header}) di tutti i
+  pacchetti uscenti, stabilendo così il numero massimo di router che i
+  pacchetti possono attraversare. Il valore può essere modificato anche per il
+  singolo socket con l'opzione \const{IP\_TTL}.  Prende un valore intero, ma
+  dato che il campo citato è di 8 bit hanno senso solo valori fra 0 e 255. Il
+  valore di default è 64, e normalmente non c'è nessuna necessità di
+  modificarlo.\footnote{l'unico motivo sarebbe per raggiungere macchine
+    estremamente ``{lontane}'' in termini di \textit{hop}, ma è praticamente
+    impossibile trovarne.} Aumentare il valore è una pratica poco gentile, in
+  quanto in caso di problemi di routing si allunga inutilmente il numero di
+  ritrasmissioni.
+
+\item[\sysctlrelfiled{net/ipv4}{ip\_forward}] abilita l'inoltro dei
+  pacchetti da una interfaccia ad un altra, e può essere impostato anche per
+  la singola interfaccia. Prende un valore logico (0 disabilita, diverso da
+  zero abilita), di default è disabilitato.
+
+\item[\sysctlrelfiled{net/ipv4}{ip\_dynaddr}] abilita la riscrittura
+  automatica degli indirizzi associati ad un socket quando una interfaccia
+  cambia indirizzo. Viene usato per le interfacce usate nei collegamenti in
+  dial-up, il cui indirizzo IP viene assegnato dinamicamente dal provider, e
+  può essere modificato. Prende un valore intero, con 0 si disabilita la
+  funzionalità, con 1 la si abilita, con 2 (o con qualunque altro valore
+  diverso dai precedenti) la si abilità in modalità \textsl{prolissa}; di
+  default la funzionalità è disabilitata.
+
+\item[\sysctlrelfiled{net/ipv4}{ip\_autoconfig}] specifica se
+  l'indirizzo IP è stato configurato automaticamente dal kernel all'avvio
+  attraverso DHCP, BOOTP o RARP. Riporta un valore logico (0 falso, 1 vero)
+  accessibile solo in lettura, è inutilizzato nei kernel recenti ed eliminato
+  a partire dal kernel 2.6.18.
+
+\item[\sysctlrelfiled{net/ipv4}{ip\_local\_port\_range}] imposta l'intervallo
+  dei valori usati per l'assegnazione delle porte effimere, permette cioè di
+  modificare i valori illustrati in fig.~\ref{fig:TCP_port_alloc}; prende due
+  valori interi separati da spazi, che indicano gli estremi
+  dell'intervallo. Si abbia cura di non definire un intervallo che si
+  sovrappone a quello delle porte usate per il \textit{masquerading}, il
+  kernel può gestire la sovrapposizione, ma si avrà una perdita di
+  prestazioni. Si imposti sempre un valore iniziale maggiore di 1024 (o meglio
+  ancora di 4096) per evitare conflitti con le porte usate dai servizi noti.
+
+\item[\sysctlrelfiled{net/ipv4}{ip\_no\_pmtu\_disc}] permette di disabilitare
+  per i socket \const{SOCK\_STREAM} la ricerca automatica della \textit{Path
+    MTU} (vedi sez.~\ref{sec:net_lim_dim} e
+  sez.~\ref{sec:sock_ipv4_options}). Prende un valore logico, e di default è
+  disabilitato (cioè la ricerca viene eseguita).
+
+  In genere si abilita questo parametro quando per qualche motivo il
+  procedimento del \textit{Path MTU discovery} fallisce; dato che questo può
+  avvenire a causa di router\footnote{ad esempio se si scartano tutti i
+    pacchetti ICMP, il problema è affrontato anche in sez.~3.4.4 di
+    \cite{SGL}.} o interfacce\footnote{ad esempio se i due capi di un
+    collegamento \textit{point-to-point} non si accordano sulla stessa MTU.}
+  mal configurati è opportuno correggere le configurazioni, perché
+  disabilitare globalmente il procedimento con questo parametro ha pesanti
+  ripercussioni in termini di prestazioni di rete.
+
+\item[\sysctlrelfiled{net/ipv4}{ip\_always\_defrag}] fa sì che tutti i
+  pacchetti IP frammentati siano riassemblati, anche in caso in successivo
+  immediato inoltro.\footnote{introdotto con il kernel 2.2.13, nelle versioni
+    precedenti questo comportamento poteva essere solo stabilito un volta per
+    tutte in fase di compilazione del kernel con l'opzione
+    \texttt{CONFIG\_IP\_ALWAYS\_DEFRAG}.} Prende un valore logico e di default
+  è disabilitato. Con i kernel dalla serie 2.4 in poi la deframmentazione
+  viene attivata automaticamente quando si utilizza il sistema del
+  \textit{netfilter}, e questo parametro non è più presente.
+
+\item[\sysctlrelfiled{net/ipv4}{ipfrag\_high\_thresh}] indica il limite
+  massimo (espresso in numero di byte) sui pacchetti IP frammentati presenti
+  in coda; quando questo valore viene raggiunto la coda viene ripulita fino al
+  valore \texttt{ipfrag\_low\_thresh}. Prende un valore intero.
+
+\item[\sysctlrelfiled{net/ipv4}{ipfrag\_low\_thresh}] indica la dimensione
+  (specificata in byte) della soglia inferiore a cui viene riportata la coda
+  dei pacchetti IP frammentati quando si raggiunge il valore massimo dato da
+  \texttt{ipfrag\_high\_thresh}. Prende un valore intero.
+
+\item[\sysctlrelfiled{net/ipv4}{ip\_nonlocal\_bind}] se abilitato rende
+  possibile ad una applicazione eseguire \func{bind} anche su un indirizzo che
+  non è presente su nessuna interfaccia locale. Prende un valore logico e di
+  default è disabilitato. La funzionalità può essere abilitata a livello di
+  singolo socket con l'opzione \const{IP\_FREEBIND} illustrata in
+  sez.~\ref{sec:sock_ipv4_options}. 
+
+  Questo può risultare utile per applicazioni particolari (come gli
+  \textit{sniffer}) che hanno la necessità di ricevere pacchetti anche non
+  diretti agli indirizzi presenti sulla macchina, ad esempio per intercettare
+  il traffico per uno specifico indirizzo che si vuole tenere sotto
+  controllo. Il suo uso però può creare problemi ad alcune applicazioni.
+
+% \item[\texttt{neigh/*}] La directory contiene i valori 
+% TODO trattare neigh/* nella parte su arp, da capire dove sarà.
+
+\end{basedescript}
+
+I file di \texttt{/proc/sys/net/ipv4} che invece fanno riferimento alle
+caratteristiche specifiche del protocollo TCP, elencati anche nella rispettiva
+pagina di manuale (accessibile con \texttt{man 7 tcp}), sono i seguenti:
+\begin{basedescript}{\desclabelwidth{2.2cm}\desclabelstyle{\nextlinelabel}}
+
+\item[\sysctlrelfiled{net/ipv4}{tcp\_abort\_on\_overflow}] indica al
+  kernel di azzerare le connessioni quando il programma che le riceve è troppo
+  lento ed incapace di accettarle. Prende un valore logico ed è disabilitato
+  di default.  Questo consente di recuperare le connessioni se si è avuto un
+  eccesso dovuto ad un qualche picco di traffico, ma ovviamente va a discapito
+  dei client che interrogano il server. Pertanto è da abilitare soltanto
+  quando si è sicuri che non è possibile ottimizzare il server in modo che sia
+  in grado di accettare connessioni più rapidamente.
+
+\item[\sysctlrelfiled{net/ipv4}{tcp\_adv\_win\_scale}] indica al kernel quale
+  frazione del buffer associato ad un socket\footnote{quello impostato con
+    \sysctlrelfile{net/ipv4}{tcp\_rmem}.} deve essere utilizzata per la
+  finestra del protocollo TCP\footnote{in sostanza il valore che costituisce
+    la \textit{advertised window} annunciata all'altro capo del socket.} e
+  quale come buffer applicativo per isolare la rete dalle latenze
+  dell'applicazione.  Prende un valore intero che determina la suddetta
+  frazione secondo la formula
+  $\texttt{buffer}/2^\texttt{tcp\_adv\_win\_scale}$ se positivo o con
+  $\texttt{buffer}-\texttt{buffer}/2^\texttt{tcp\_adv\_win\_scale}$ se
+  negativo.  Il default è 2 che significa che al buffer dell'applicazione
+  viene riservato un quarto del totale.
+
+\item[\sysctlrelfiled{net/ipv4}{tcp\_app\_win}] indica la frazione della
+  finestra TCP che viene riservata per gestire l'overhaed dovuto alla
+  bufferizzazione. Prende un valore intero che consente di calcolare la
+  dimensione in byte come il massimo fra la MSS e
+  $\texttt{window}/2^\texttt{tcp\_app\_win}$. Un valore nullo significa che
+  non viene riservato nessuno spazio; il valore di default è 31.
+
+% vecchi, presumibilmente usati quando gli algoritmi di congestione non erano
+% modularizzabili 
+% \item[\texttt{tcp\_bic}]
+% \item[\texttt{tcp\_bic\_low\_window}] 
+% \item[\texttt{tcp\_bic\_fast\_convergence}] 
+
+\item[\sysctlrelfiled{net/ipv4}{tcp\_dsack}] abilita il supporto,
+  definito nell'\href{http://www.ietf.org/rfc/rfc2884.txt}{RFC~2884}, per il
+  cosiddetto \textit{Duplicate SACK}.\footnote{si indica con SACK
+    (\textit{Selective Acknowledgement}) un'opzione TCP, definita
+    nell'\href{http://www.ietf.org/rfc/rfc2018.txt}{RFC~2018}, usata per dare
+    un \textit{acknowledgement} unico su blocchi di pacchetti non contigui,
+    che consente di diminuire il numero di pacchetti scambiati.} Prende un
+  valore logico e di default è abilitato.
+% TODO documentare o descrivere che cos'è il Duplicate SACK o
+% mettere riferimento nelle appendici
+
+
+\item[\sysctlrelfiled{net/ipv4}{tcp\_ecn}] abilita il meccanismo della
+  \textit{Explicit Congestion Notification} (in breve ECN) nelle connessioni
+  TCP. Prende valore logico che di default è disabilitato. La \textit{Explicit
+    Congestion Notification} \itindex{Explicit~Congestion~Notification~(ECN)}
+  è un meccanismo che consente di notificare quando una rotta o una rete è
+  congestionata da un eccesso di traffico,\footnote{il meccanismo è descritto
+    in dettaglio nell'\href{http://www.ietf.org/rfc/rfc3168.txt}{RFC~3168}
+    mentre gli effetti sulle prestazioni del suo utilizzo sono documentate
+    nell'\href{http://www.ietf.org/rfc/rfc2884.txt}{RFC~2884}.} si può così
+  essere avvisati e cercare rotte alternative oppure diminuire l'emissione di
+  pacchetti (in modo da non aumentare la congestione).
+
+  Si tenga presente che se si abilita questa opzione si possono avere dei
+  malfunzionamenti apparentemente casuali dipendenti dalla destinazione,
+  dovuti al fatto che alcuni vecchi router non supportano il meccanismo ed
+  alla sua attivazione scartano i relativi pacchetti, bloccando completamente
+  il traffico.
+% TODO documentare o descrivere che cos'è l'Explicit Congestion Notification o
+% mettere riferimento nelle appendici
+
+
+\item[\sysctlrelfiled{net/ipv4}{tcp\_fack}] abilita il supporto per il
+  \textit{TCP Forward Acknowledgement}, un algoritmo per il controllo della
+  congestione del traffico. Prende un valore logico e di default è abilitato.
+
+% TODO documentare o descrivere che cos'è il TCP Forward Acknowledgement o
+% mettere riferimento nelle appendici
+
+\item[\sysctlrelfiled{net/ipv4}{tcp\_fin\_timeout}] specifica il numero di
+  secondi da passare in stato \texttt{FIN\_WAIT2} nell'attesa delle ricezione
+  del pacchetto FIN conclusivo, passati quali il socket viene comunque chiuso
+  forzatamente.  Prende un valore intero che indica i secondi e di default è
+  60.\footnote{nei kernel della serie 2.2.x era il valore utilizzato era
+    invece di 120 secondi.} L'uso di questa opzione realizza quella che in
+  sostanza è una violazione delle specifiche del protocollo TCP, ma è utile
+  per fronteggiare alcuni attacchi di \textit{Denial of Service}.
+
+\item[\sysctlrelfiled{net/ipv4}{tcp\_frto}] abilita il supporto per
+  l'algoritmo F-RTO, un algoritmo usato per la ritrasmissione dei timeout del
+  protocollo TCP, che diventa molto utile per le reti wireless dove la perdita
+  di pacchetti è usualmente dovuta a delle interferenze radio, piuttosto che
+  alla congestione dei router. Prende un valore logico e di default è
+  disabilitato.
+
+\item[\sysctlrelfiled{net/ipv4}{tcp\_keepalive\_intvl}] indica il
+  numero di secondi che deve trascorrere fra l'emissione di due successivi
+  pacchetti di test quando è abilitata la funzionalità del \textit{keepalive}
+  (vedi sez.~\ref{sec:sock_options_main}). Prende un valore intero che di
+  default è 75.
+
+\item[\sysctlrelfiled{net/ipv4}{tcp\_keepalive\_probes}] indica il
+  massimo numero pacchetti di \textit{keepalive} (vedi
+  sez.~\ref{sec:sock_options_main}) che devono essere inviati senza ricevere
+  risposta prima che il kernel decida che la connessione è caduta e la
+  termini. Prende un valore intero che di default è 9.
+
+\item[\sysctlrelfiled{net/ipv4}{tcp\_keepalive\_time}] indica il numero di
+  secondi che devono passare senza traffico sulla connessione prima che il
+  kernel inizi ad inviare pacchetti di \textit{keepalive}.\footnote{ha effetto
+    solo per i socket per cui si è impostata l'opzione \const{SO\_KEEPALIVE}
+    (vedi sez.~\ref{sec:sock_options_main}.}  Prende un valore intero che di
+  default è 7200, pari a due ore.
+
+\item[\sysctlrelfiled{net/ipv4}{tcp\_low\_latency}] indica allo stack
+  TCP del kernel di ottimizzare il comportamento per ottenere tempi di latenza
+  più bassi a scapito di valori più alti per l'utilizzo della banda. Prende un
+  valore logico che di default è disabilitato in quanto un maggior utilizzo
+  della banda è preferito, ma esistono applicazioni particolari in cui la
+  riduzione della latenza è più importante (ad esempio per i cluster di
+  calcolo parallelo) nelle quali lo si può abilitare.
+
+\item[\sysctlrelfiled{net/ipv4}{tcp\_max\_orphans}] indica il numero
+  massimo di socket TCP ``\textsl{orfani}'' (vale a dire non associati a
+  nessun file descriptor) consentito nel sistema.\footnote{trattasi in genere
+    delle connessioni relative a socket chiusi che non hanno completato il
+    processo di chiusura.}  Quando il limite viene ecceduto la connessione
+  orfana viene resettata e viene stampato un avvertimento. Questo limite viene
+  usato per contrastare alcuni elementari attacchi di \textit{denial of
+    service}.  Diminuire il valore non è mai raccomandato, in certe condizioni
+  di rete può essere opportuno aumentarlo, ma si deve tenere conto del fatto
+  che ciascuna connessione orfana può consumare fino a 64K di memoria del
+  kernel. Prende un valore intero, il valore di default viene impostato
+  inizialmente al valore del parametro del kernel \texttt{NR\_FILE}, e viene
+  aggiustato a seconda della memoria disponibile.
+
+% TODO verificare la spiegazione di connessione orfana.
+
+\item[\sysctlrelfiled{net/ipv4}{tcp\_max\_syn\_backlog}] indica la lunghezza
+  della coda delle connessioni incomplete, cioè delle connessioni per le quali
+  si è ricevuto un SYN di richiesta ma non l'ACK finale del \textit{three way
+    handshake} (si riveda quanto illustrato in
+  sez.~\ref{sec:TCP_func_listen}).
+
+  Quando questo valore è superato il kernel scarterà immediatamente ogni
+  ulteriore richiesta di connessione. Prende un valore intero; il default, che
+  è 256, viene automaticamente portato a 1024 qualora nel sistema ci sia
+  sufficiente memoria (se maggiore di 128Mb) e ridotto a 128 qualora la
+  memoria sia poca (inferiore a 32Mb).\footnote{si raccomanda, qualora si
+    voglia aumentare il valore oltre 1024, di seguire la procedura citata
+    nella pagina di manuale di TCP, e modificare il valore della costante
+    \texttt{TCP\_SYNQ\_HSIZE} nel file \texttt{include/net/tcp.h} dei sorgenti
+    del kernel, in modo che sia $\mathtt{tcp\_max\_syn\_backlog} \ge
+    \mathtt{16*TCP\_SYNQ\_HSIZE}$, per poi ricompilare il kernel.}
+
+\item[\sysctlrelfiled{net/ipv4}{tcp\_max\_tw\_buckets}] indica il
+  numero massimo di socket in stato \texttt{TIME\_WAIT} consentito nel
+  sistema. Prende un valore intero di default è impostato al doppio del valore
+  del parametro \texttt{NR\_FILE}, ma che viene aggiustato automaticamente a
+  seconda della memoria presente. Se il valore viene superato il socket viene
+  chiuso con la stampa di un avviso; l'uso di questa funzionalità consente di
+  prevenire alcuni semplici attacchi di \textit{denial of service}.
+  
+
+\item[\sysctlrelfiled{net/ipv4}{tcp\_mem}] viene usato dallo stack TCP
+  per gestire le modalità con cui esso utilizzerà la memoria. Prende una
+  tripletta di valori interi, che indicano un numero di pagine:
+
+  \begin{itemize*}
+  \item il primo valore, chiamato \textit{low} nelle pagine di manuale, indica
+    il numero di pagine allocate sotto il quale non viene usato nessun
+    meccanismo di regolazione dell'uso della memoria.
+
+  \item il secondo valore, chiamato \textit{pressure} indica il numero di
+    pagine allocate passato il quale lo stack TCP inizia a moderare il suo
+    consumo di memoria; si esce da questo stato di \textsl{pressione} sulla
+    memoria quando il numero di pagine scende sotto il precedente valore
+    \textit{low}.
+
+  \item il terzo valore, chiamato \textit{high} indica il numero massimo di
+    pagine che possono essere utilizzate dallo stack TCP/IP, e soprassiede
+    ogni altro valore specificato dagli altri limiti del kernel.
+  \end{itemize*}
+
+\item[\sysctlrelfiled{net/ipv4}{tcp\_orphan\_retries}] indica il numero
+  massimo di volte che si esegue un tentativo di controllo sull'altro capo di
+  una connessione che è stata già chiusa dalla nostra parte. Prende un valore
+  intero che di default è 8.
+
+\item[\sysctlrelfiled{net/ipv4}{tcp\_reordering}] indica il numero
+  massimo di volte che un pacchetto può essere riordinato nel flusso di dati,
+  prima che lo stack TCP assuma che è andato perso e si ponga nello stato di
+  \textit{slow start} (si veda sez.~\ref{sec:tcp_protocol_xxx}) viene usata
+  questa metrica di riconoscimento dei riordinamenti per evitare inutili
+  ritrasmissioni provocate dal riordinamento. Prende un valore intero che di
+  default che è 3, e che non è opportuno modificare.
+
+\item[\sysctlrelfiled{net/ipv4}{tcp\_retrans\_collapse}] in caso di
+  pacchetti persi durante una connessione, per ottimizzare l'uso della banda
+  il kernel cerca di eseguire la ritrasmissione inviando pacchetti della
+  massima dimensione possibile; in sostanza dati che in precedenza erano stati
+  trasmessi su pacchetti diversi possono essere ritrasmessi riuniti su un solo
+  pacchetto (o su un numero minore di pacchetti di dimensione
+  maggiore). Prende un valore logico e di default è abilitato.
+
+\item[\sysctlrelfiled{net/ipv4}{tcp\_retries1}] imposta il massimo
+  numero di volte che protocollo tenterà la ritrasmissione si un pacchetto su
+  una connessione stabilita prima di fare ricorso ad ulteriori sforzi che
+  coinvolgano anche il livello di rete. Passato questo numero di
+  ritrasmissioni verrà fatto eseguire al livello di rete un tentativo di
+  aggiornamento della rotta verso la destinazione prima di eseguire ogni
+  successiva ritrasmissione. Prende un valore intero che di default è 3.
+
+\item[\sysctlrelfiled{net/ipv4}{tcp\_retries2}] imposta il numero di
+  tentativi di ritrasmissione di un pacchetto inviato su una connessione già
+  stabilita per il quale non si sia ricevuto una risposta di ACK (si veda
+  anche quanto illustrato in sez.~\ref{sec:TCP_server_crash}). Prende un
+  valore intero che di default è 15, il che comporta un tempo variabile fra 13
+  e 30 minuti; questo non corrisponde a quanto richiesto
+  nell'\href{http://www.ietf.org/rfc/rfc1122.txt}{RFC~1122} dove è indicato un
+  massimo di 100 secondi, che però è un valore considerato troppo basso.
+
+\item[\sysctlrelfiled{net/ipv4}{tcp\_rfc1337}] indica al kernel di
+  abilitare il comportamento richiesto
+  nell'\href{http://www.ietf.org/rfc/rfc1337.txt}{RFC~1337}. Prende un valore
+  logico e di default è disabilitato, il che significa che alla ricezione di
+  un segmento RST in stato \texttt{TIME\_WAIT} il socket viene chiuso
+  immediatamente senza attendere la conclusione del periodo di
+  \texttt{TIME\_WAIT}.
+
+\item[\sysctlrelfiled{net/ipv4}{tcp\_rmem}] viene usato dallo stack TCP
+  per controllare dinamicamente le dimensioni dei propri buffer di ricezione,
+  anche in rapporto alla memoria disponibile.  Prende una tripletta di valori
+  interi separati da spazi che indicano delle dimensioni in byte:
+
+  \begin{itemize}
+  \item il primo valore, chiamato \textit{min} nelle pagine di manuale, indica
+    la dimensione minima in byte del buffer di ricezione; il default è 4Kb, ma
+    in sistemi con poca memoria viene automaticamente ridotto a
+    \const{PAGE\_SIZE}.  Questo valore viene usato per assicurare che anche in
+    situazioni di pressione sulla memoria (vedi quanto detto per
+    \sysctlrelfile{net/ipv4}{tcp\_rmem}) le allocazioni al di sotto di
+    questo limite abbiamo comunque successo.  Questo valore non viene comunque
+    ad incidere sulla dimensione del buffer di ricezione di un singolo socket
+    dichiarata con l'opzione \const{SO\_RCVBUF}.
+
+  \item il secondo valore, denominato \textit{default} nelle pagine di
+    manuale, indica la dimensione di default, in byte, del buffer di ricezione
+    di un socket TCP.  Questo valore sovrascrive il default iniziale impostato
+    per tutti i socket con \sysctlfile{net/core/mem\_default} che vale per
+    qualunque protocollo. Il default è 87380 byte, ridotto a 43689 per sistemi
+    con poca memoria. Se si desiderano dimensioni più ampie per tutti i socket
+    si può aumentare questo valore, ma se si vuole che in corrispondenza
+    aumentino anche le dimensioni usate per la finestra TCP si deve abilitare
+    il \textit{TCP window scaling} (di default è abilitato, vedi più avanti
+    \sysctlrelfile{net/ipv4}{tcp\_window\_scaling}).
+
+  \item il terzo valore, denominato \textit{max} nelle pagine di manuale,
+    indica la dimensione massima in byte del buffer di ricezione di un socket
+    TCP; il default è 174760 byte, che viene ridotto automaticamente a 87380
+    per sistemi con poca memoria. Il valore non può comunque eccedere il
+    limite generale per tutti i socket posto con
+    \sysctlfile{net/core/rmem\_max}. Questo valore non viene ad
+    incidere sulla dimensione del buffer di ricezione di un singolo socket
+    dichiarata con l'opzione \const{SO\_RCVBUF}.
+  \end{itemize}
+
+\item[\sysctlrelfiled{net/ipv4}{tcp\_sack}] indica al kernel di
+  utilizzare il meccanismo del \textit{TCP selective acknowledgement} definito
+  nell'\href{http://www.ietf.org/rfc/rfc2018.txt}{RFC~2018}. Prende un valore
+  logico e di default è abilitato.
+
+\item[\sysctlrelfiled{net/ipv4}{tcp\_stdurg}] indica al kernel di
+  utilizzare l'interpretazione che viene data
+  dall'\href{http://www.ietf.org/rfc/rfc1122.txt}{RFC~1122} del puntatore dei
+  \textit{dati urgenti} (vedi sez.~\ref{sec:TCP_urgent_data}) in cui questo
+  punta all'ultimo byte degli stessi; se disabilitato viene usata
+  l'interpretazione usata da BSD per cui esso punta al primo byte successivo.
+  Prende un valore logico e di default è disabilitato, perché abilitarlo può
+  dar luogo a problemi di interoperabilità.
+
+\item[\sysctlrelfiled{net/ipv4}{tcp\_synack\_retries}] indica il numero
+  massimo di volte che verrà ritrasmesso il segmento SYN/ACK nella creazione di
+  una connessione (vedi sez.~\ref{sec:TCP_conn_cre}). Prende un valore intero
+  ed il valore di default è 5; non si deve superare il valore massimo di 255.
+
+\item[\sysctlrelfiled{net/ipv4}{tcp\_syncookies}] abilita i \textit{TCP
+    syncookies}.\footnote{per poter usare questa funzionalità è necessario
+    avere abilitato l'opzione \texttt{CONFIG\_SYN\_COOKIES} nella compilazione
+    del kernel.} Prende un valore logico, e di default è disabilitato. Questa
+  funzionalità serve a fornire una protezione in caso di un attacco di tipo
+  \textit{SYN flood}, e deve essere utilizzato come ultima risorsa dato che
+  costituisce una violazione del protocollo TCP e confligge con altre
+  funzionalità come le estensioni e può causare problemi per i client ed il
+  reinoltro dei pacchetti.
+
+\item[\sysctlrelfiled{net/ipv4}{tcp\_syn\_retries}] imposta il numero di
+  tentativi di ritrasmissione dei pacchetti SYN di inizio connessione del
+  \textit{three way handshake} (si ricordi quanto illustrato in
+  sez.~\ref{sec:TCP_func_connect}). Prende un valore intero che di default è
+  5; non si deve superare il valore massimo di 255.
+
+\item[\sysctlrelfiled{net/ipv4}{tcp\_timestamps}] abilita l'uso dei
+  \textit{TCP timestamps}, come definiti
+  nell'\href{http://www.ietf.org/rfc/rfc1323.txt}{RFC~1323}. Prende un valore
+  logico e di default è abilitato.
+
+\item[\sysctlrelfiled{net/ipv4}{tcp\_tw\_recycle}] abilita il riutilizzo
+  rapido dei socket in stato \texttt{TIME\_WAIT}. Prende un valore logico e di
+  default è disabilitato. Non è opportuno abilitare questa opzione che può
+  causare problemi con il NAT.\footnote{la
+    \itindex{Network~Address~Translation~(NAT)} \textit{Network Address
+      Translation} (abbreviato in NAT) è una tecnica, impiegata nei firewall e
+    nei router, che consente di modificare al volo gli indirizzi dei pacchetti
+    che transitano per una macchina, Linux la supporta con il
+    \textit{netfilter}.}
+
+\item[\sysctlrelfiled{net/ipv4}{tcp\_tw\_reuse}] abilita il riutilizzo
+  dello stato \texttt{TIME\_WAIT} quando questo è sicuro dal punto di vista
+  del protocollo. Prende un valore logico e di default è disabilitato. 
+
+\item[\sysctlrelfiled{net/ipv4}{tcp\_window\_scaling}] un valore
+  logico, attivo di default, che abilita la funzionalità del
+  \itindex{TCP~window~scaling} \textit{TCP window scaling} definita
+  dall'\href{http://www.ietf.org/rfc/rfc1323.txt}{RFC~1323}. Prende un valore
+  logico e di default è abilitato. Come accennato in
+  sez.~\ref{sec:TCP_TCP_opt} i 16 bit della finestra TCP comportano un limite
+  massimo di dimensione di 64Kb, ma esiste una opportuna opzione del
+  protocollo che permette di applicare un fattore di scale che consente di
+  aumentarne le dimensioni. Questa è pienamente supportata dallo stack TCP di
+  Linux, ma se lo si disabilita la negoziazione del
+  \itindex{TCP~window~scaling} \textit{TCP window scaling} con l'altro capo
+  della connessione non viene effettuata.
+
+%\item[\sysctlrelfiled{net/ipv4}{tcp\_vegas\_cong\_avoid}] 
+% TODO: controllare su internet
+
+%\item[\sysctlrelfiled{net/ipv4}{tcp\_westwood}] 
+% TODO: controllare su internet
+
+\item[\sysctlrelfiled{net/ipv4}{tcp\_wmem}] viene usato dallo stack TCP
+  per controllare dinamicamente le dimensioni dei propri buffer di spedizione,
+  adeguandole in rapporto alla memoria disponibile.  Prende una tripletta di
+  valori interi separati da spazi che indicano delle dimensioni in byte:
+
+  \begin{itemize}
+  \item il primo valore, chiamato \textit{min}, indica la dimensione minima in
+    byte del buffer di spedizione; il default è 4Kb. Come per l'analogo di
+    \sysctlrelfile{net/ipv4}{tcp\_rmem}) viene usato per assicurare
+    che anche in situazioni di pressione sulla memoria (vedi
+    \sysctlrelfile{net/ipv4}{tcp\_mem}) le allocazioni al di sotto di
+    questo limite abbiamo comunque successo.  Di nuovo questo valore non viene
+    ad incidere sulla dimensione del buffer di trasmissione di un singolo
+    socket dichiarata con l'opzione \const{SO\_SNDBUF}.
+
+  \item il secondo valore, denominato \textit{default}, indica la dimensione
+    di default in byte del buffer di spedizione di un socket TCP.  Questo
+    valore sovrascrive il default iniziale impostato per tutti i tipi di
+    socket sul file \sysctlfile{net/core/wmem\_default}. Il default è 87380
+    byte, ridotto a 43689 per sistemi con poca memoria. Si può aumentare
+    questo valore quando si desiderano dimensioni più ampie del buffer di
+    trasmissione per i socket TCP, ma come per il precedente
+    \sysctlrelfile{net/ipv4}{tcp\_rmem}) se si vuole che in corrispondenza
+    aumentino anche le dimensioni usate per la finestra TCP si deve abilitare
+    il \textit{TCP window scaling} con
+    \sysctlrelfile{net/ipv4}{tcp\_window\_scaling}.
+
+  \item il terzo valore, denominato \textit{max}, indica la dimensione massima
+    in byte del buffer di spedizione di un socket TCP; il default è 128Kb, che
+    viene ridotto automaticamente a 64Kb per sistemi con poca memoria. Il
+    valore non può comunque eccedere il limite generale per tutti i socket
+    posto con \sysctlfile{net/core/wmem\_max}. Questo valore non viene
+    ad incidere sulla dimensione del buffer di trasmissione di un singolo
+    socket dichiarata con l'opzione \const{SO\_SNDBUF}.
+  \end{itemize}
+
+\end{basedescript}
+
+
+
+% LocalWords:  socket sez dotted decimal resolver Domain Name Service cap DNS
+% LocalWords:  client fig LDAP Lightweight Access Protocol NIS Information Sun
+% LocalWords:  like netgroup Switch Solaris glibc libc uclib NSS tab shadow uid
+% LocalWords:  username group aliases ethers MAC address hosts networks rpc RPC
+% LocalWords:  protocols services dns db lib libnss org truelite it root res HS
+% LocalWords:  resource init netinet resolv int void conf host LOCALDOMAIN TCP
+% LocalWords:  options DEBUG debug AAONLY USEVC UDP PRIMARY IGNTC RECURSE INET
+% LocalWords:  DEFNAMES search STAYOPEN DNSRCH INSECURE NOALIASES HOSTALIASES
+% LocalWords:  IPv gethostbyname NOCHECKNAME KEEPTSIG TSIG BLAST RETRY retry NS
+% LocalWords:  retrans query FQDN Fully Qualified const char dname class type
+% LocalWords:  unsigned answer anslen CSNET Hesiod MIT CHAOS Chaosnet ANY BIND
+% LocalWords:  nameser compat Berkley MF CNAME SOA MB MR NULL WKS PTR HINFO TXT
+% LocalWords:  MINFO RP responsible person AFSDB AFS RT router NSAP SIG KEY PX
+% LocalWords:  GPOS AAAA LOC NXT EID NIMLOC nimrod SRV ATMA ATM NAPTR naming AF
+% LocalWords:  authority IXFR AXFR MAILB MAILA errno NOT FOUND RECOVERY TRY err
+% LocalWords:  AGAIN herror netdb string perror error hstrerror strerror struct
+% LocalWords:  hostent name addrtype length addr list sys af mygethost inet ret
+% LocalWords:  ntop deep copy buf size buflen result errnop value argument len
+% LocalWords:  ERANGE sethostent stayopen endhostent gethostbyaddr order pton
+% LocalWords:  getipnodebyname getipnodebyaddr flags num MAPPED ALL ADDRCONFIG
+% LocalWords:  freehostent ip getXXXbyname getXXXbyaddr servent getservbyname
+% LocalWords:  netent getnetbyname getnetbyaddr protoent smtp udp
+% LocalWords:  getprotobyname getprotobyaddr getservbyport port tcp setservent
+% LocalWords:  getservent endservent setXXXent getXXXent endXXXent gethostent
+% LocalWords:  setnetent getnetent endnetent setprotoent getprotoent POSIX RFC
+% LocalWords:  endprotoent getaddrinfo getnameinfo nell' node service addrinfo
+% LocalWords:  hints linked addrlen socklen family socktype protocol sockaddr
+% LocalWords:  canonname next PF UNSPEC SOCK STREAM DGRAM bind INADDR loopback
+% LocalWords:  connect sendto NUMERICHOST EAI NONAME SYSTEM BADFLAGS ADDRFAMILY
+% LocalWords:  NODATA MEMORY FAIL errcode echo mygetaddr ptr casting Canonical
+% LocalWords:  freeaddrinfo getservname salen hostlen serv servlen l'OR NI NUL
+% LocalWords:  NOFQDN NAMEREQD NUMERICSERV MAXHOST MAXSERV sockconn SockUtil of
+% LocalWords:  descriptor hint fifth sockbind setsockopt getsockopt sock level
+% LocalWords:  optname optval optlen EBADF EFAULT EINVAL ENOPROTOOPT ENOTSOCK
+% LocalWords:  IPPROTO Stevens ICMP ICMPV ICMPv get KEEPALIVE OOBINLINE timeval
+% LocalWords:  RCVLOWAT SNDLOWAT RCVTIMEO SNDTIMEO BSDCOMPAT BSD PASSCRED ucred
+% LocalWords:  PEERCRED BINDTODEVICE REUSEADDR ACCEPTCONN DONTROUTE gateway MSG
+% LocalWords:  BROADCAST broadcast SNDBUF RCVBUF LINGER linger PRIORITY read IF
+% LocalWords:  OOB recvmsg kernel select write readv recv recvfrom EAGAIN send
+% LocalWords:  EWOULDBLOCK writev sendmsg raw domain SCM CREDENTIALS eth packet
+% LocalWords:  IFNAMSIZ capabilities capability ADMIN log trpt EADDRINUSE close
+% LocalWords:  listen routing sysctl shutdown Quality TOS keep alive ACK RST to
+% LocalWords:  ECONNRESET ETIMEDOUT keepalive echod fourth newsgroup WAIT reuse
+% LocalWords:  sockbindopt SockUtils homed completely binding RECVDSTADDR onoff
+% LocalWords:  PKTINFO getsockname multicast streaming unicast REUSEPORT reset
+% LocalWords:  stealing ling RECVTOS RECVTTL TTL RECVOPTS RETOPTS HDRINCL MTU
+% LocalWords:  RECVERR DISCOVER Path Discovery ALERT alert ADD MEMBERSHIP mreqn
+% LocalWords:  pktinfo ipi ifindex spec dst RECVIF Live IPTOS LOWDELAY Advanced
+% LocalWords:  Transfer Unit PMTUDISC DONT WANT route dall' pmtu EMSGSIZE imr
+% LocalWords:  multiaddr mreq fcntl ioctl request SIOCGSTAMP trip SIOCSPGRP pid
+% LocalWords:  process SIGIO SIGURG KILL FIOASYNC SIOCGPGRP filesystem proc ttl
+% LocalWords:  rmem wmem message cost burst bucket filter netdev backlog optmem
+% LocalWords:  forward dynaddr dial autoconfig local masquerading ipfrag high
+% LocalWords:  thresh low always defrag CONFIG SETSIG cmd FIOGETOWN FIOSETOWN
+% LocalWords:  quest'ultime neigh dev weight cong mod somaxconn Di SIOCINQ DoS
+% LocalWords:  Documentation SIOCATMARK SIOCOUTQ FIONREAD TIOCOUTQ Denial work
+% LocalWords:  netfilter scheduler mark ARP DHCP BOOTP RARP nonlocal sniffer is
+% LocalWords:  linux NODELAY MAXSEG CORK KEEPIDLE KEEPINTVL KEEPCNT SYNCNT INFO
+% LocalWords:  DEFER ACCEPT WINDOW CLAMP QUICKACK CONGESTION ENCAP urgent MSS
+% LocalWords:  Segment SYN accept advertised window info quickack Nagle ifreq
+% LocalWords:  ifr ppp union EPERM SIOCGIFNAME dell' interface index IFF NOARP
+% LocalWords:  SIOCGIFINDEX SIOCGIFFLAGS POINTOPOINT RUNNING PROMISC NOTRAILERS
+% LocalWords:  ALLMULTI bundle PORTSEL ifmap AUTOMEDIA DYNAMIC SIOCSIFFLAGS way
+% LocalWords:  SIOCGIFMETRIC SIOCSIFMETRIC SIOCGIFMTU SIOCSIFMTU SIOCGIFHWADDR
+% LocalWords:  SIOCSIFHWADDR SIOCSIFHWBROADCAST SIOCGIFMAP SIOCSIFMAP sendfile
+% LocalWords:  SIOCADDMULTI SIOCDELMULTI SIOCGIFTXQLEN SIOCSIFTXQLEN three syn
+% LocalWords:  SIOCSIFNAME SIOCGIFCONF handshake retries MIN FreeBSD closing Mb
+% LocalWords:  abort overflow adv win app bic convergence dsack ecn fack frto
+% LocalWords:  intvl probes latency orphans l'ACK SYNQ HSIZE tw buckets mem rfc
+% LocalWords:  orphan reordering collapse sack stdurg synack syncookies recycle
+% LocalWords:  timestamps scaling vegas avoid westwood tcpi l'incapsulazione NR
+% LocalWords:  metric EOPNOTSUPP mtu hwaddr ARPHRD interrupt DMA map qlen silly
+% LocalWords:  rename ifconf syndrome dell'ACK FTP ACCEPTFILTER advanced reno
+% LocalWords:  congestion control Networking cubic CUBIC highspeed HSTCP htcp
+% LocalWords:  HTCP hybla HYBLA scalable SCALABLE ifc req iflist access ntoa Kb
+% LocalWords:  hop Selective acknowledgement Explicit RTO stack firewall passwd
+% LocalWords:  Notification wireless denial pressure ATTACH DETACH publickey
+% LocalWords:  libpcap discovery point l'overhaed min PAGE flood NFS blast
+% LocalWords:  selective COOKIES NAT Translation
+
+%%% Local Variables: 
+%%% mode: latex
+%%% TeX-master: "gapil"
+%%% End: 
 
-%%% Local Variables: 
-%%% mode: latex
-%%% TeX-master: "gapil"
-%%% End: