+\index{costante!{SO\_KEEPALIVE}@{{\tt {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}\footnote{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_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_xxx}), 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}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{15cm}
+ \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
+verrano comunque chiuse per cui, utilizzando ad esempio una \func{select}, se
+be 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.
+\index{costante!{SO\_KEEPALIVE}@{{\tt {SO\_KEEPALIVE}}}|)}
+
+
+
+\index{costante!{SO\_REUSEADDR}@{{\tt {SO\_REUSEADDR}}}|(}
+\subsubsection{L'opzione \const{SO\_REUSEADDR}}
+
+La seconda opzione da approfondire è \const{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, che è anche il più comune, in cui si fa ricorso a
+\const{SO\_REUSEADDR} è 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 sui newsgroup dedicati 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}).
+
+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 \func{sockbind} (vedi fig.~\ref{fig:sockbind_code})
+che consenta l'impostazione di questa opzione. La nuova funzione è
+\func{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.
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{15cm}
+ \includecodesample{listati/sockbindopt.c}
+ \end{minipage}
+ \normalsize
+ \caption{Le sezioni della funzione \func{sockbindopt} modificate rispetto al
+ codice della precedente \func{sockbind}.}
+ \label{fig:sockbindopt_code}
+\end{figure}
+
+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}.
+
+
+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}.
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{15cm}
+ \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 \func{sockbindopt}.}
+ \label{fig:TCP_echod_fifth}
+\end{figure}
+
+Il secondo caso in cui viene usata \const{SO\_REUSEADDR} è quando si ha una
+macchina cui sono assegnati diversi numeri 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. Infine si tenga presente che con il
+protocollo TCP non è mai possibile far partire server che eseguano \func{bind}
+sullo stesso indirizzo e la stessa porta, cioè ottenere quello che viene
+chiamato un \textit{completely duplicate binding}.
+
+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 \const{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. Questo ovviamente non ha senso per il normale traffico di rete,
+in cui i pacchetti vengono scambiati direttamente fra due applicazioni; ma
+quando un sistema supporta il traffico in \itindex{multicast}
+\textit{multicast}, in cui una applicazione invia i pacchetti a molte altre
+(vedi sez.~\ref{sec:multicast_xxx}), allora ha senso che su una macchina i
+pacchetti provenienti dal traffico in \itindex{multicast} \textit{multicast}
+possano essere ricevuti da più applicazioni\footnote{l'esempio classico di
+ traffico in \textit{multicast} è quello di uno streaming di dati (audio,
+ video, ecc.), l'uso del \textit{multicast} consente in tal caso di
+ trasmettere un solo pacchetto, che potrà essere ricevuto da 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.} o da diverse istanze della stessa applicazione.
+\itindex{multicast}
+
+In questo caso utilizzando \const{SO\_REUSEADDR} si consente ad una
+applicazione eseguire \func{bind} sulla stessa porta ed indirizzo usata da
+un'altra, così che anche essa possa ricevere gli stessi pacchetti (chiaramente
+la cosa non ha alcun senso per i socket TCP, ed infatti in questo tipo di
+applicazione è normale l'uso del protocollo UDP). La regola è che quando si
+hanno più applicazioni che hanno eseguito \func{bind} sulla stessa porta, di
+tutti pacchetti destinati ad un indirizzo di \itindex{broadcast}
+\textit{broadcast} o di \itindex{multicast} \textit{multicast} viene inviata
+una copia a ciascuna applicazione. Non è definito invece cosa accade qualora
+il pacchetto sia destinato ad un indirizzo normale (unicast).
+
+Essendo questo un caso particolare in alcuni sistemi (come BSD) è stata
+introdotta una opzione ulteriore, \const{SO\_REUSEPORT} che richiede che detta
+opzione sia specificata per tutti i socket per i quali si vuole eseguire il
+\textit{completely duplicate binding}. Nel caso di Linux questa opzione non
+esiste, ma il comportamento di \const{SO\_REUSEADDR} è analogo, sarà cioè
+possibile effettuare un \textit{completely duplicate binding} ed ottenere il
+successo di \func{bind} su un socket legato allo stesso indirizzo e porta solo
+se il programma che ha eseguito per primo \func{bind} su di essi ha impostato
+questa opzione.\footnote{Questa restrizione permette di evitare il cosiddetto
+ \textit{port stealing}, in cui un programma, usando \const{SO\_REUSEADDR},
+ può collegarsi ad una porta già in uso e ricevere i pacchetti destinati ad
+ un altro programma; con questa caratteristica ciò è possibile soltanto se il
+ primo programma a consentirlo, avendo usato fin dall'inizio
+ \const{SO\_REUSEADDR}.}
+
+\index{costante!{SO\_REUSEADDR}@{{\tt {SO\_REUSEADDR}}}|)}
+
+\index{costante!{SO\_LINGER}@{{\tt {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]{15cm}
+ \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}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{15cm}
+ \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}.
+
+\index{costante!{SO\_LINGER}@{{\tt {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.\footnote{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}.} Se si vuole operare su queste opzioni generiche il
+livello da utilizzare è \const{SOL\_IP} (o l'equivalente \const{IPPROTO\_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 \file{netinet/ip.h}, ed accessibili includendo detto file.
+
+\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{IP\_OPTIONS} &$\bullet$&$\bullet$&&\texttt{void *}& %???
+ imposta o riceve le opzioni di IP.\\
+ \const{IP\_PKTINFO} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ passa un messaggio di informazione.\\
+ \const{IP\_RECVTOS} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ passa un messaggio col campo TOS.\\
+ \const{IP\_RECVTTL} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ passa un messaggio col campo TTL.\\
+ \const{IP\_RECVOPTS} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ passa un messaggio con le opzioni IP.\\
+ \const{IP\_RETOPTS} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ passa un messaggio con le opzioni IP non trattate.\\
+ \const{IP\_TOS} &$\bullet$&$\bullet$& &\texttt{int}&
+ imposta il valore del campo TOS.\\
+ \const{IP\_TTL} &$\bullet$&$\bullet$& &\texttt{int}&
+ imposta il valore del campo TTL.\\
+ \const{IP\_HDRINCL} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ passa l'intestazione di IP nei dati.\\
+ \const{IP\_RECVERR} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ abilita la gestione degli errori.\\
+ \const{IP\_MTU\_DISCOVER} &$\bullet$&$\bullet$& &\texttt{int}&
+ imposta il Path MTU Discovery.\\
+ \const{IP\_MTU} &$\bullet$& & &\texttt{int}&
+ legge il valore attuale della MTU.\\
+ \const{IP\_ROUTER\_ALERT} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ imposta l'opzione \textit{IP router alert} sui pacchetti.\\
+ \const{IP\_MULTICAST\_TTL} &$\bullet$&$\bullet$& &\texttt{int}&
+ imposta il TTL per i pacchetti \itindex{multicast} \textit{multicast}.\\
+ \const{IP\_MULTICAST\_LOOP} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ controlla il reinvio a se stessi dei dati di \itindex{multicast}
+ \textit{multicast}.\\
+ \const{IP\_ADD\_MEMBERSHIP} & &$\bullet$& &\struct{ip\_mreqn}&
+ si unisce a un gruppo di \itindex{multicast} \textit{multicast}.\\
+ \const{IP\_DROP\_MEMBERSHIP}& &$\bullet$& &\struct{ip\_mreqn}&
+ si sgancia da un gruppo di \textit{multicast}.\\
+ \const{IP\_MULTICAST\_IF} & &$\bullet$& &\struct{ip\_mreqn}&
+ imposta l'interfaccia locale di un socket \itindex{multicast}
+ \textit{multicast}.\\
+ \hline
+ \end{tabular}
+ \caption{Le opzioni disponibili al livello \const{SOL\_IP}.}
+ \label{tab:sock_opt_iplevel}
+\end{table}
+
+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.5cm}\desclabelstyle{\nextlinelabel}}
+
+
+\item[\const{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[\const{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}), 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]{15cm}
+ \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[\const{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[\const{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[\const{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[\const{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[\const{IP\_TOS}] L'opzione consente di leggere o impostare il campo
+ \textit{Type of Service} dell'intestazione IP (vedi
+ 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 \itindex{capabilities} 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[\const{IP\_TTL}] L'opzione consente di leggere o impostare il campo
+ \textit{Time to Live} dell'intestazione IP (vedi sez.~\ref{sec:IP_header})
+ per tutti i pacchetti associati al socket. Il campo TTL è di 8 bit e
+ l'opzione richiede che \param{optval} sia un intero, che ne conterrà il
+ valore.
+
+\item[\const{IP\_HDRINCL}] Se abilitata l'utente deve fornire lui stesso
+ l'intestazione IP in cima 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}
+
+\item[\const{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}.
+
+\itindbeg{Maximum~Transfer~Unit}
+\item[\const{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 Maximum Transfer Unit} (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
+ \const{IP\_PMTUDISC\_DONT}&0& Non effettua la ricerca dalla \textit{Path
+ MTU}.\\
+ \const{IP\_PMTUDISC\_WANT}&1& Utilizza il valore impostato per la rotta
+ utilizzata dai pacchetti (dal comando
+ \texttt{route}).\\
+ \const{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}.\\
+ \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.}
+
+\item[\const{IP\_MTU}] Permette di leggere il valore della \textit{Path MTU}
+ di percorso 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 potrà 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.
+
+\itindend{Maximum~Transfer~Unit}
+
+\item[\const{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.
+
+\itindbeg{multicast}
+\item[\const{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.
+
+\item[\const{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[\const{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).
+
+ Per compatibilità è possibile utilizzare anche un argomento di tipo
+ \struct{ip\_mreq}, una precedente versione di \struct{ip\_mreqn}, che
+ differisce da essa soltanto per l'assenza del campo \var{imr\_ifindex}.
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{15cm}
+ \includestruct{listati/ip_mreqn.h}
+ \end{minipage}
+ \caption{La struttura \structd{ip\_mreqn} utilizzata dalle opzioni dei
+ socket per le operazioni concernenti l'appartenenza ai gruppi di
+ \textit{multicast}.}
+ \label{fig:ip_mreqn_struct}
+\end{figure}
+
+\item[\const{IP\_DROP\_MEMBERSHIP}] Lascia un gruppo di \textit{multicast},
+ prende per \param{optval} la stessa struttura \struct{ip\_mreqn} (o
+ \struct{ip\_mreq}) usata anche per \const{IP\_ADD\_MEMBERSHIP}.
+
+\item[\const{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.
+
+\itindend{multicast}
+\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
+\const{IPPROTO\_TCP}) come valore per l'argomento \param{level}. Si sono
+riportate le varie opzioni disponibili in tab.~\ref{tab:sock_opt_tcp}, 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 \file{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{linux/tcp.h}, 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 \itindex{Maximum~Segment~Size} 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 \itindex{advertised~window} \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{?}& %???
+ non ancora documentata.\\
+ \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{3.3cm}\desclabelstyle{\nextlinelabel}}
+
+\item[\const{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 \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
+ l'\textsl{algoritmo di Nagle}.} Questo meccanismo è controllato da un
+ apposito algoritmo (detto \textsl{algoritmo di Nagle}, vedi
+ sez.\ref{sez: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[\const{TCP\_MAXSEG}] con questa opzione si legge o si imposta il valore
+ della \itindex{Maximum~Segment~Size} MSS (vedi sez.~\ref{sec:net_lim_dim} e
+ sez.\ref{sez:tcp_protocol_xxx}) dei segmenti TCP uscenti. Se l'opzione è
+ impostata prima di stabilire la connessione, si cambia anche il valore della
+ \itindex{Maximum~Segment~Size} 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[\const{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}), 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[\const{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[\const{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[\const{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[\const{TCP\_SYNCNT}] con questa opzione si legge o si imposta il numero
+ di tentativi di ritrasmissione dei segmenti SYN usati nel
+ \itindex{three~way~handshake} \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[\const{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[\const{TCP\_DEFER\_ACCEPT}] questa opzione consente di modificare il
+ comportamento standard del protocollo TCP nello stabilirsi di una
+ connessione; se ricordiamo il meccanismo del \itindex{three~way~handshake}
+ \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 utilie inviare immediatamente la richiesta all'interno
+ del segmento con l'ultimo ACK del \itindex{three~way~handshake}
+ \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 \itindex{three~way~handshake}
+ \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 fà usualmente è lanciare un nuovo processo per leggere i
+ successivi dati che si bloccherà su una \func{read} se questi non sono
+ disponibili, ma così si saranno impiegate delle risorse (per la creazione
+ del nuovo processo) che non saranno 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
+ \itindex{three~way~handshake} \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[\const{TCP\_WINDOW\_CLAMP}] con questa opzione si legge o si imposta
+ alla dimensione specificata, in byte, il valore dichiarato della
+ \itindex{advertised~window} \textit{advertised window} (vedi
+ sez.\ref{sez: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.
+
+\item[\const{TCP\_INFO}] questa opzione, specifica di Linux, ma introdotta
+ anche in altri kernel (ad esempio FreeBSD) permette di controllare lo stato
+ di un socket TCP in 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 relativi al socket.
+ Anche questa opzione deve essere evitata se si vuole scrivere codice
+ portabile.
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{15cm}
+ \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}
+
+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}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{15cm}
+ \includestruct{listati/tcp_info.h}
+ \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}
+
+\item[\const{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[\const{TCP\_CONGESTION}] questa opzione permette di controllare gli
+ algoritmi usati dal protocollo TCP per la gestione della connessione. É
+ stata introdotta con il kernel 2.6.13, e non è documentata.
+
+\end{basedescript}
+
+
+Il protocollo UDP, anche per la sua maggiore semplicità, supporta un numero
+ridotto di opzioni, riportate in tab.~\ref{tab:sock_opt_udp}; anche in questo
+caso per poterle utilizzare occorrerà impostare l'opportuno valore per
+l'argomento \param{level}, che è \const{SOL\_UDP} (o l'equivalente
+\const{IPPROTO\_UDP}). Le costanti che identificano dette opzioni sono
+definite in \file{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{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
+ \const{UDP\_CORK} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& %???
+ accumula tutti i dati su un unico pacchetto.\\
+ \const{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}
+
+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{2.5cm}\desclabelstyle{\nextlinelabel}}
+
+\item[\const{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[\const{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} e sez.~\ref{sec:file_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 in sez.~\ref{sec:file_fcntl} e
+sez.~\ref{sec:file_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 \itindex{value~result~argument} \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{2.5cm}\desclabelstyle{\nextlinelabel}}
+\item[\const{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
+ \itindex{Round~Trip~Time} \textit{Round Trip Time} cui abbiamo già
+ accennato in sez.~\ref{sec:net_tcp}.} dei pacchetti sulla rete.
+
+\item[\const{SIOCSPGRP}] imposta il processo o il \itindex{process~group}
+ \textit{process group} a cui inviare i segnali \const{SIGIO} e
+ \const{SIGURG} quando viene completata una operazione di I/O asincrono o
+ arrivano dei dati urgenti \itindex{out-of-band} (\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 \acr{pid} del
+ processo, mentre un valore negativo indica (col valore assoluto) il
+ \textit{process group}. Senza privilegi di amministratore o la capability
+ \const{CAP\_KILL} si può impostare solo se stessi o il proprio
+ \textit{process group}.
+
+\item[\const{SIOCGPGRP}] legge le impostazioni presenti sul socket
+ relativamente all'eventuale processo o \itindex{process~group}
+ \textit{process group} cui devono essere inviati i segnali \const{SIGIO} e
+ \const{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:file_asyncronous_operation})
+ che verrà inviato il segnale di \const{SIGIO} (o quanto impostato con
+ \const{F\_SETSIG}, vedi sez.~\ref{sec:file_fcntl}) 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]{15cm}
+ \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 \ctyp{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 \itindex{capabilities}
+\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{2.7cm}\desclabelstyle{\nextlinelabel}}
+\item[\const{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 \index{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; si può ottenere un elenco delle interfacce che
+ contiene anche il valore del relativo indice usando il comando \cmd{ip
+ link}.
+
+\item[\const{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[\const{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
+ \const{IFF\_UP} & l'interfaccia è attiva.\\
+ \const{IFF\_BROADCAST} & l'interfaccia ha impostato un indirizzo di
+ \itindex{broadcast} \textit{broadcast} valido.\\
+ \const{IFF\_DEBUG} & è attivo il flag interno di debug.\\
+ \const{IFF\_LOOPBACK} & l'interfaccia è una interfaccia di
+ \textit{loopback}.\\
+ \const{IFF\_POINTOPOINT}& l'interfaccia è associata ad un collegamento
+ \textsl{punto-punto}.\\
+ \const{IFF\_RUNNING} & l'interfaccia ha delle risorse allocate (non può
+ quindi essere disattivata).\\
+ \const{IFF\_NOARP} & l'interfaccia ha il protocollo ARP disabilitato o
+ l'indirizzo del livello di rete non è impostato.\\
+ \const{IFF\_PROMISC} & l'interfaccia è in \index{modo~promiscuo}
+ \textsl{modo promiscuo} (riceve cioè tutti i
+ pacchetti che vede passare, compresi quelli non
+ direttamente indirizzati a lei).\\
+ \const{IFF\_NOTRAILERS}& evita l'uso di \textit{trailer} nei pacchetti.\\
+ \const{IFF\_ALLMULTI} & riceve tutti i pacchetti di \itindex{multicast}
+ \textit{multicast}.\\
+ \const{IFF\_MASTER} & l'interfaccia è il master di un bundle per il
+ bilanciamento di carico.\\
+ \const{IFF\_SLAVE} & l'interfaccia è uno slave di un bundle per il
+ bilanciamento di carico.\\
+ \const{IFF\_MULTICAST} & l'interfaccia ha il supporto per il
+ \textit{multicast} \itindex{multicast} attivo.\\
+ \const{IFF\_PORTSEL} & l'interfaccia può impostare i suoi parametri
+ hardware (con l'uso di \struct{ifmap})..\\
+ \const{IFF\_AUTOMEDIA} & l'interfaccia è in grado di selezionare
+ automaticamente il tipo di collegamento.\\
+ \const{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[\const{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[\const{SIOCGIFMETRIC}] permette di leggere il valore della metrica del
+ dispositivo associato all'interfaccia specificata nel campo
+ \var{ifr\_metric}, attualmente non ancora implementato, restituisce sempre 0
+ come valore.
+
+\item[\const{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[\const{SIOCGIFMTU}] permette di leggere il valore della
+ \itindex{Maximum~Transfer~Unit} \textit{Maximum Transfer Unit} del
+ dispositivo nel campo \var{ifr\_mtu}.
+
+\item[\const{SIOCSIFMTU}] permette di impostare il valore della
+ \itindex{Maximum~Transfer~Unit} \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[\const{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[\const{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[\const{SIOCSIFHWBROADCAST}] imposta l'indirizzo \textit{broadcast}
+ \itindex{broadcast} hardware dell'interfaccia al valore specificato dal
+ campo \var{ifr\_hwaddr}. L'operazione è privilegiata.
+
+\item[\const{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]{15cm}
+ \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[\const{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[\const{SIOCADDMULTI}] aggiunge un indirizzo di \itindex{multicast}
+ \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[\const{SIOCDELMULTI}] rimuove un indirizzo di \itindex{multicast}
+ \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[\const{SIOCGIFTXQLEN}] permette di leggere la lunghezza della coda di
+ trasmissione del dispositivo associato all'interfaccia specificata nel campo
+ \var{ifr\_qlen}.
+
+\item[\const{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[\const{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}
+
+Una ulteriore operazione che consente di ricavare le caratteristiche delle
+interfacce di rete, che però è disponibile soltanto per socket della famiglia
+\const{AF\_INET} (vale ad dire per socket IPv4), è \const{SIOCGIFCONF}. 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]{15cm}
+ \includestruct{listati/ifconf.h}
+ \end{minipage}
+ \caption{La struttura \structd{ifconf}.}
+ \label{fig:netdevice_ifconf_struct}
+\end{figure}
+
+
+
+
+\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 \itindex{value~result~argument} \textit{value result argument}, deve
+essere sempre il puntatore ad una variabile di tipo \ctyp{int}:
+\begin{basedescript}{\desclabelwidth{2.5cm}\desclabelstyle{\nextlinelabel}}
+\item[\const{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[\const{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
+ \itindex{out-of-band} 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[\const{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 \itindex{value~result~argument}
+\textit{value result argument} e deve essere un puntatore ad una variabile di
+tipo \ctyp{int}:
+\begin{basedescript}{\desclabelwidth{2.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 sottonodi 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
+sottonodi 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.5cm}\desclabelstyle{\nextlinelabel}}
+\item[\texttt{rmem\_default}] imposta la dimensione di default del buffer di
+ lettura (cioè per i dati in ingresso) dei socket.
+\item[\texttt{rmem\_max}] imposta la dimensione massima che si può assegnare al
+ buffer di ingresso dei socket attraverso l'uso dell'opzione
+ \const{SO\_RCVBUF}.
+\item[\texttt{wmem\_default}] imposta la dimensione di default del buffer di
+ scrittura (cioè per i dati in uscita) dei socket.
+\item[\texttt{wmem\_max}] imposta la dimensione massima che si può assegnare al
+ buffer di uscita dei socket attraverso l'uso dell'opzione
+ \const{SO\_SNDBUF}.
+\item[\texttt{message\_cost}, \texttt{message\_burst}] contengono le
+ impostazioni del \itindex{bucket~filter} \textit{bucket filter} che
+ controlla l'emissione di messaggi di avviso da parte kernel per eventi
+ relativi a problemi sulla rete, imponendo un limite che consente di
+ prevenire eventuali attacchi di \itindex{Denial~of~Service~(DoS)}
+ \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.}
+
+ Il \itindex{bucket~filter} \textit{bucket filter} è un algoritmo generico
+ che permette di impostare dei limiti di flusso su una quantità\footnote{uno
+ analogo viene usato nel \index{netfilter} \textit{netfilter} per imporre
+ dei limiti sul flusso dei pacchetti.} 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}.
+
+ 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[\texttt{netdev\_max\_backlog}] numero massimo di pacchetti che possono
+ essere contenuti nella coda di ingresso generale.
+
+\item[\texttt{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 altri
+file, la cui documentazione 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{3.0cm}\desclabelstyle{\nextlinelabel}}
+\item[\texttt{dev\_weight}] blocco di lavoro (\textit{work quantum}) dello
+ scheduler di processo dei pacchetti. % TODO da documentare meglio
+
+\item[\texttt{lo\_cong}] valore per l'occupazione della coda di ricezione
+ sotto la quale si considera di avere una bassa congestione.
+
+\item[\texttt{mod\_cong}] valore per l'occupazione della coda di ricezione
+ sotto la quale si considera di avere una congestione moderata.
+
+\item[\texttt{no\_cong}] valore per l'occupazione della coda di ricezione
+ sotto la quale si si considera di non avere congestione.
+
+\item[\texttt{no\_cong\_thresh}] valore minimo (\textit{low water mark}) per
+ il riavvio dei dispositivi congestionati.
+
+%\item[\texttt{netdev\_fastroute}] è presente soltanto quando si è compilato il
+% kernel con l'apposita opzione di ottimizzazione per l'uso come router (.
+
+\item[\texttt{somaxconn}] imposta la dimensione massima del \textit{backlog}
+ della funzione \func{listen} (vedi sez.~\ref{sec:TCP_func_listen}), e
+ corrisponde al valore della costante \const{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, descritti anche nella pagina di manuale
+accessibile con \texttt{man 7 ip}, sono i seguenti:
+\begin{basedescript}{\desclabelwidth{3.5cm}\desclabelstyle{\nextlinelabel}}
+
+\item[\texttt{ip\_default\_ttl}] imposta il valore di default per il campo TTL
+ (vedi sez.~\ref{sec:IP_header}) di tutti i pacchetti uscenti. Il valore può
+ essere modificato per il singolo socket con l'opzione \const{IP\_TTL}.
+ Prende un valore intero.
+
+\item[\texttt{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).
+
+\item[\texttt{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. Un
+ valore nullo disabilita la funzionalità, con 1 la si abilita, con 2 la si
+ abilità in modalità \textsl{prolissa}.
+
+\item[\texttt{ip\_autoconfig}] Specifica se l'indirizzo IP è stato configurato
+ automaticamente via DHCP, BOOTP o RARP.
+
+\item[\texttt{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
+ numerici, che indicano gli estremi dell'intervallo. Si abbia cura di non
+ definire un intervallo che si sovrappone a quello delle porte usate per il
+ \itindex{masquerading} \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[\texttt{ip\_no\_pmtu\_disc}] imposta la disciplina di ricerca della
+ \textit{Path MTU} (vedi sez.~\ref{sec:net_lim_dim} e
+ sez.~\ref{sec:sock_ipv4_options}).
+
+\item[\texttt{ipfrag\_high\_thresh}] limite massimo (espresso in numero di
+ byte) sui pacchetti IP frammentati presenti in coda; quando questo valore
+ viene raggiunta la coda viene ripulita fino al valore
+ \texttt{ipfrag\_low\_thresh}.
+
+\item[\texttt{ipfrag\_low\_thresh}] soglia bassa (specificata in byte) cui
+ viene riportata la coda dei pacchetti IP frammentati quando si raggiunge il
+ valore \texttt{ipfrag\_high\_thresh}.
+
+\item[\texttt{ip\_always\_defrag}] se abilitato (prende un intero come valore
+ logico) tutti i pacchetti IP frammentati saranno riassemblati, anche in caso
+ in successivo immediato inoltro.\footnote{introdotto con il kernel 2.2.13,
+ nelle versioni precedenti questo comportamento poteva essere solo in fase
+ di compilazione del kernel con l'opzione
+ \texttt{CONFIG\_IP\_ALWAYS\_DEFRAG}.}
+
+\item[\texttt{ip\_nonlocal\_bind}] se abilitato (prende un intero come valore
+ logico) è possibile che una applicazione possa collegarsi (con \func{bind}
+ su un indirizzo non locale. 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.
+
+% \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{3.9cm}\desclabelstyle{\nextlinelabel}}
+\item[\texttt{tcp\_abort\_on\_overflow}]
+\item[\texttt{tcp\_adv\_win\_scale}]
+\item[\texttt{tcp\_app\_win}]
+\item[\texttt{tcp\_bic\_low\_window}]
+\item[\texttt{tcp\_bic\_fast\_convergence}]
+\item[\texttt{tcp\_dsack}]
+\item[\texttt{tcp\_ecn}]
+\item[\texttt{tcp\_fack}]
+
+\item[\texttt{tcp\_fin\_timeout}] specifica il numero di secondi (il default è
+ 60\footnote{nei kernel della serie 2.2.x era invece di 120 secondi.}) da
+ passare in stato \texttt{FIN\_WAIT2} nell'attesa delle ricezione del
+ pacchetto FIN conclusivo, passati quali il socket viene comunque chiuso
+ forzatamente. L'uso di questa opzione realizza quella che in sostanza è una
+ violazione delle specifiche del protocollo TCP, ma è utile per fronteggiare
+ alcuni attacchi di \itindex{Denial~of~Service~(DoS)} \textit{Denial of
+ Service}.
+
+
+\item[\texttt{tcp\_frto}]
+\item[\texttt{tcp\_keepalive\_intvl}]
+\item[\texttt{tcp\_keepalive\_probes}]
+\item[\texttt{tcp\_keepalive\_time}]
+\item[\texttt{tcp\_low\_latency}]
+\item[\texttt{tcp\_max\_orphans}]
+
+\item[\texttt{tcp\_max\_syn\_backlog}] un numero intero che 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
+ \itindex{three~way~handshake} \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. Il valore di 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[\texttt{tcp\_max\_tw\_buckets}]
+\item[\texttt{tcp\_mem}]
+\item[\texttt{tcp\_orphan\_retries}]
+\item[\texttt{tcp\_reordering}]
+\item[\texttt{tcp\_retrans\_collapse}]
+\item[\texttt{tcp\_retries1}]
+
+\item[\texttt{tcp\_retries2}] imposta il numero di tentativi di ritrasmissione
+ (il default è 15) 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}).
+
+
+\item[\texttt{tcp\_rfc1337}]
+\item[\texttt{tcp\_rmem}]
+\item[\texttt{tcp\_sack}]
+\item[\texttt{tcp\_stdurg}]
+\item[\texttt{tcp\_synack\_retries}]
+\item[\texttt{tcp\_syncookies}]
+
+\item[\texttt{tcp\_syn\_retries}] imposta il numero di tentativi (il default è
+ 5) di ritrasmissione dei pacchetti SYN di inizio connessione del
+ \itindex{three~way~handshake} \textit{three way handshake} (si ricordi
+ quanto illustrato in sez.\ref{sec:TCP_func_connect}). Il valore non deve
+ superare 255.
+
+\item[\texttt{tcp\_timestamps}]
+\item[\texttt{tcp\_tw\_recycle}]
+\item[\texttt{tcp\_tw\_reuse}]
+\item[\texttt{tcp\_window\_scaling}]
+\item[\texttt{tcp\_vegas\_cong\_avoid}]
+\item[\texttt{tcp\_westwood}]
+\item[\texttt{tcp\_wmem}]
+\end{basedescript}
+