+ inviano occorre che questa funzionalità sia abilitata (come avviene di
+ default). Qualora però non si voglia generare traffico per dati che già sono
+ disponibili in locale l'uso di questa opzione permette di disabilitare
+ questo tipo di traffico.
+
+\item[\constd{IP\_MULTICAST\_TTL}] L'opzione permette di impostare o leggere il
+ valore del campo TTL per i pacchetti \textit{multicast} in uscita associati
+ al socket. È importante che questo valore sia il più basso possibile, ed il
+ default è 1, che significa che i pacchetti non potranno uscire dalla rete
+ locale. Questa opzione consente ai programmi che lo richiedono di superare
+ questo limite. L'opzione richiede per
+ \param{optval} un intero che conterrà il valore del TTL.
+% TODO chiarire quale è la struttura \struct{ip\_mreq}
+
+\item[\constd{IP\_OPTIONS}] l'opzione permette di impostare o leggere le
+ opzioni del protocollo IP (si veda sez.~\ref{sec:IP_options}). L'opzione
+ prende come valore dell'argomento \param{optval} un puntatore ad un buffer
+ dove sono mantenute le opzioni, mentre \param{optlen} indica la dimensione
+ di quest'ultimo. Quando la si usa con \func{getsockopt} vengono lette le
+ opzioni IP utilizzate per la spedizione, quando la si usa con
+ \func{setsockopt} vengono impostate le opzioni specificate. L'uso di questa
+ opzione richiede una profonda conoscenza del funzionamento del protocollo,
+ torneremo in parte sull'argomento in sez.~\ref{sec:sock_IP_options}.
+
+\item[\constd{IP\_PKTINFO}] Quando abilitata l'opzione permette di ricevere
+ insieme ai pacchetti un messaggio ancillare (vedi
+ sez.~\ref{sec:net_ancillary_data}) di tipo \const{IP\_PKTINFO} contenente
+ una struttura \struct{pktinfo} (vedi fig.~\ref{fig:sock_pktinfo_struct}) che
+ mantiene una serie di informazioni riguardo i pacchetti in arrivo. In
+ particolare è possibile conoscere l'interfaccia su cui è stato ricevuto un
+ pacchetto (nel campo \var{ipi\_ifindex}),\footnote{in questo campo viene
+ restituito il valore numerico dell'indice dell'interfaccia,
+ sez.~\ref{sec:sock_ioctl_netdevice}.} l'indirizzo locale da esso
+ utilizzato (nel campo \var{ipi\_spec\_dst}) e l'indirizzo remoto dello
+ stesso (nel campo \var{ipi\_addr}).
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{0.80\textwidth}
+ \includestruct{listati/pktinfo.h}
+ \end{minipage}
+ \caption{La struttura \structd{pktinfo} usata dall'opzione
+ \const{IP\_PKTINFO} per ricavare informazioni sui pacchetti di un socket
+ di tipo \const{SOCK\_DGRAM}.}
+ \label{fig:sock_pktinfo_struct}
+\end{figure}
+
+
+L'opzione è utilizzabile solo per socket di tipo \const{SOCK\_DGRAM}. Questa è
+una opzione introdotta con i kernel della serie 2.2.x, ed è specifica di
+Linux;\footnote{non dovrebbe pertanto essere utilizzata se si ha a cuore la
+ portabilità.} essa permette di sostituire le opzioni \const{IP\_RECVDSTADDR}
+e \const{IP\_RECVIF} presenti in altri Unix (la relativa informazione è quella
+ottenibile rispettivamente dai campi \var{ipi\_addr} e \var{ipi\_ifindex} di
+\struct{pktinfo}).
+
+L'opzione prende per \param{optval} un intero usato come valore logico, che
+specifica soltanto se insieme al pacchetto deve anche essere inviato o
+ricevuto il messaggio \const{IP\_PKTINFO} (vedi
+sez.~\ref{sec:net_ancillary_data}); il messaggio stesso dovrà poi essere
+letto o scritto direttamente con \func{recvmsg} e \func{sendmsg} (vedi
+sez.~\ref{sec:net_sendmsg}).
+
+\item[\constd{IP\_RECVERR}] Questa è una opzione introdotta con i kernel della
+ serie 2.2.x, ed è specifica di Linux. Essa permette di usufruire di un
+ meccanismo affidabile per ottenere un maggior numero di informazioni in caso
+ di errori. Se l'opzione è abilitata tutti gli errori generati su un socket
+ vengono memorizzati su una coda, dalla quale poi possono essere letti con
+ \func{recvmsg} (vedi sez.~\ref{sec:net_sendmsg}) come messaggi ancillari
+ (torneremo su questo in sez.~\ref{sec:net_ancillary_data}) di tipo
+ \const{IP\_RECVERR}. L'opzione richiede per \param{optval} un intero usato
+ come valore logico e non è applicabile a socket di tipo
+ \const{SOCK\_STREAM}.
+
+\item[\constd{IP\_RECVOPTS}] Quando abilitata l'opzione permette di ricevere
+ insieme ai pacchetti un messaggio ancillare (vedi
+ sez.~\ref{sec:net_ancillary_data}) di tipo \const{IP\_OPTIONS}, contenente
+ le opzioni IP del protocollo (vedi sez.~\ref{sec:IP_options}). Le
+ intestazioni di instradamento e le altre opzioni sono già riempite con i
+ dati locali. L'opzione richiede per \param{optval} un intero usato come
+ valore logico. L'opzione non è supportata per socket di tipo
+ \const{SOCK\_STREAM}.
+
+\item[\constd{IP\_RECVTOS}] Quando abilitata l'opzione permette di ricevere
+ insieme ai pacchetti un messaggio ancillare (vedi
+ sez.~\ref{sec:net_ancillary_data}) di tipo \const{IP\_TOS}, che contiene un
+ byte con il valore del campo \textit{Type of Service} dell'intestazione IP
+ del pacchetto stesso (vedi sez.~\ref{sec:IP_header}). Prende per
+ \param{optval} un intero usato come valore logico.
+
+\item[\constd{IP\_RECVTTL}] Quando abilitata l'opzione permette di ricevere
+ insieme ai pacchetti un messaggio ancillare (vedi
+ sez.~\ref{sec:net_ancillary_data}) di tipo \const{IP\_RECVTTL}, contenente
+ un byte con il valore del campo \textit{Time to Live} dell'intestazione IP
+ (vedi sez.~\ref{sec:IP_header}). L'opzione richiede per \param{optval} un
+ intero usato come valore logico. L'opzione non è supportata per socket di
+ tipo \const{SOCK\_STREAM}.
+
+\item[\constd{IP\_RETOPTS}] Identica alla precedente \const{IP\_RECVOPTS}, ma
+ in questo caso restituisce i dati grezzi delle opzioni, senza che siano
+ riempiti i capi di instradamento e le marche temporali. L'opzione richiede
+ per \param{optval} un intero usato come valore logico. L'opzione non è
+ supportata per socket di tipo \const{SOCK\_STREAM}.
+
+\item[\constd{IP\_ROUTER\_ALERT}] Questa è una opzione introdotta con i
+ kernel della serie 2.2.x, ed è specifica di Linux. Prende per
+ \param{optval} un intero usato come valore logico. Se abilitata
+ passa tutti i pacchetti con l'opzione \textit{IP Router Alert} (vedi
+ sez.~\ref{sec:IP_options}) che devono essere inoltrati al socket
+ corrente. Può essere usata soltanto per socket di tipo raw.
+
+\item[\constd{IP\_TOS}] L'opzione consente di leggere o impostare il campo
+ \textit{Type of Service} dell'intestazione IP (per una trattazione più
+ dettagliata, che riporta anche i valori possibili e le relative costanti di
+ definizione si veda sez.~\ref{sec:IP_header}) che permette di indicare le
+ priorità dei pacchetti. Se impostato il valore verrà mantenuto per tutti i
+ pacchetti del socket; alcuni valori (quelli che aumentano la priorità)
+ richiedono i privilegi di amministrazione con la \textit{capability}
+ \const{CAP\_NET\_ADMIN}.
+
+ Il campo TOS è di 8 bit e l'opzione richiede per \param{optval} un intero
+ che ne contenga il valore. Sono definite anche alcune costanti che
+ definiscono alcuni valori standardizzati per il \textit{Type of Service},
+ riportate in tab.~\ref{tab:IP_TOS_values}, il valore di default usato da
+ Linux è \const{IPTOS\_LOWDELAY}, ma esso può essere modificato con le
+ funzionalità del cosiddetto \textit{Advanced Routing}. Si ricordi che la
+ priorità dei pacchetti può essere impostata anche in maniera indipendente
+ dal protocollo utilizzando l'opzione \const{SO\_PRIORITY} illustrata in
+ sez.~\ref{sec:sock_generic_options}.
+
+\item[\constd{IP\_TTL}] L'opzione consente di leggere o impostare per tutti i
+ pacchetti associati al socket il campo \textit{Time to Live}
+ dell'intestazione IP che indica il numero massimo di \textit{hop} (passaggi
+ da un router ad un altro) restanti al paccheto (per una trattazione più
+ estesa si veda sez.~\ref{sec:IP_header}). Il campo TTL è di 8 bit e
+ l'opzione richiede che \param{optval} sia un intero, che ne conterrà il
+ valore.
+\end{basedescript}
+
+
+
+\subsection{Le opzioni per i protocolli TCP e UDP}
+\label{sec:sock_tcp_udp_options}
+
+In questa sezione tratteremo le varie opzioni disponibili per i socket che
+usano i due principali protocolli di comunicazione del livello di trasporto;
+UDP e TCP.\footnote{come per le precedenti, una descrizione di queste opzioni
+ è disponibile nella settima sezione delle pagine di manuale, che si può
+ consultare rispettivamente con \texttt{man 7 tcp} e \texttt{man 7 udp}; le
+ pagine di manuale però, alla stesura di questa sezione (Agosto 2006) sono
+ alquanto incomplete.} Dato che questi due protocolli sono entrambi
+trasportati su IP,\footnote{qui si sottintende IPv4, ma le opzioni per TCP e
+ UDP sono le stesse anche quando si usa IPv6.} oltre alle opzioni generiche
+di sez.~\ref{sec:sock_generic_options} saranno comunque disponibili anche le
+precedenti opzioni di sez.~\ref{sec:sock_ipv4_options}.\footnote{in realtà in
+ sez.~\ref{sec:sock_ipv4_options} si sono riportate le opzioni per IPv4, al
+ solito, qualora si stesse utilizzando IPv6, si potrebbero utilizzare le
+ opzioni di quest'ultimo.}
+
+Il protocollo che supporta il maggior numero di opzioni è TCP; per poterle
+utilizzare occorre specificare \const{SOL\_TCP} (o l'equivalente
+\constd{IPPROTO\_TCP}) come valore per l'argomento \param{level}. Si sono
+riportate le varie opzioni disponibili in tab.~\ref{tab:sock_opt_tcplevel},
+dove sono elencate le rispettive costanti da utilizzare come valore per
+l'argomento \param{optname}. Dette costanti e tutte le altre costanti e
+strutture collegate all'uso delle opzioni TCP sono definite in
+\headfiled{netinet/tcp.h}, ed accessibili includendo detto file.\footnote{in
+ realtà questo è il file usato dalle librerie; la definizione delle opzioni
+ effettivamente supportate da Linux si trova nel file
+ \texttt{include/linux/tcp.h} dei sorgenti del kernel, dal quale si sono
+ estratte le costanti di tab.~\ref{tab:sock_opt_tcplevel}.}
+
+\begin{table}[!htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|c|c|c|l|l|}
+ \hline
+ \textbf{Opzione}&\texttt{get}&\texttt{set}&\textbf{flag}&\textbf{Tipo}&
+ \textbf{Descrizione}\\
+ \hline
+ \hline
+ \const{TCP\_NODELAY} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Spedisce immediatamente i dati in segmenti singoli.\\
+ \const{TCP\_MAXSEG} &$\bullet$&$\bullet$& &\texttt{int}&
+ Valore della MSS per i segmenti in uscita.\\
+ \const{TCP\_CORK} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Accumula i dati in un unico segmento.\\
+ \const{TCP\_KEEPIDLE} &$\bullet$&$\bullet$& &\texttt{int}&
+ Tempo in secondi prima di inviare un \textit{keepalive}.\\
+ \const{TCP\_KEEPINTVL} &$\bullet$&$\bullet$& &\texttt{int}&
+ Tempo in secondi prima fra \textit{keepalive} successivi.\\
+ \const{TCP\_KEEPCNT} &$\bullet$&$\bullet$& &\texttt{int}&
+ Numero massimo di \textit{keepalive} inviati.\\
+ \const{TCP\_SYNCNT} &$\bullet$&$\bullet$& &\texttt{int}&
+ Numero massimo di ritrasmissioni di un SYN.\\
+ \const{TCP\_LINGER2} &$\bullet$&$\bullet$& &\texttt{int}&
+ Tempo di vita in stato \texttt{FIN\_WAIT2}.\\
+ \const{TCP\_DEFER\_ACCEPT}&$\bullet$&$\bullet$& &\texttt{int}&
+ Ritorna da \func{accept} solo in presenza di dati.\\
+ \const{TCP\_WINDOW\_CLAMP}&$\bullet$&$\bullet$& &\texttt{int}&
+ Valore della \textit{advertised window}.\\
+ \const{TCP\_INFO} &$\bullet$& & &\struct{tcp\_info}&
+ Restituisce informazioni sul socket.\\
+ \const{TCP\_QUICKACK} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Abilita la modalità \textit{quickack}.\\
+ \const{TCP\_CONGESTION} &$\bullet$&$\bullet$& &\texttt{char *}&
+ Imposta l'algoritmo per il controllo della congestione.\\
+ \hline
+ \end{tabular}
+ \caption{Le opzioni per i socket TCP disponibili al livello
+ \const{SOL\_TCP}.}
+ \label{tab:sock_opt_tcplevel}
+\end{table}
+
+Le descrizioni delle varie opzioni riportate in
+tab.~\ref{tab:sock_opt_tcplevel} sono estremamente sintetiche ed indicative,
+la spiegazione del funzionamento delle singole opzioni con una maggiore
+quantità di dettagli è fornita nel seguente elenco:
+\begin{basedescript}{\desclabelwidth{1.5cm}\desclabelstyle{\nextlinelabel}}
+
+\item[\constd{TCP\_NODELAY}] il protocollo TCP utilizza un meccanismo di
+ bufferizzazione dei dati uscenti, per evitare la trasmissione di tanti
+ piccoli segmenti con un utilizzo non ottimale della banda
+ disponibile.\footnote{il problema è chiamato anche
+ \itindex{silly~window~syndrome} \textit{silly window syndrome}, per averne
+ un'idea si pensi al risultato che si ottiene quando un programma di
+ terminale invia un segmento TCP per ogni tasto premuto, 40 byte di
+ intestazione di protocollo con 1 byte di dati trasmessi; per evitare
+ situazioni del genere è stato introdotto \index{algoritmo~di~Nagle}
+ l'\textsl{algoritmo di Nagle}.} Questo meccanismo è controllato da un
+ apposito algoritmo (detto \textsl{algoritmo di Nagle}, vedi
+ sez.~\ref{sec:tcp_protocol_xxx}). Il comportamento normale del protocollo
+ prevede che i dati siano accumulati fintanto che non si raggiunge una
+ quantità considerata adeguata per eseguire la trasmissione di un singolo
+ segmento.
+
+ Ci sono però delle situazioni in cui questo comportamento può non essere
+ desiderabile, ad esempio quando si sa in anticipo che l'applicazione invierà
+ soltanto un piccolo quantitativo di dati;\footnote{è il caso classico di una
+ richiesta HTTP.} in tal caso l'attesa introdotta dall'algoritmo di
+ bufferizzazione non soltanto è inutile, ma peggiora le prestazioni
+ introducendo un ritardo. Impostando questa opzione si disabilita l'uso
+ dell'\textsl{algoritmo di Nagle} ed i dati vengono inviati immediatamente in
+ singoli segmenti, qualunque sia la loro dimensione. Ovviamente l'uso di
+ questa opzione è dedicato a chi ha esigenze particolari come quella
+ illustrata, che possono essere stabilite solo per la singola applicazione.
+
+ Si tenga conto che questa opzione viene sovrascritta dall'eventuale
+ impostazione dell'opzione \const{TCP\_CORK} (il cui scopo è sostanzialmente
+ l'opposto) che blocca l'invio immediato. Tuttavia quando la si abilita viene
+ sempre forzato lo scaricamento della coda di invio (con conseguente
+ trasmissione di tutti i dati pendenti), anche qualora si fosse già abilitata
+ \const{TCP\_CORK}.\footnote{si tenga presente però che \const{TCP\_CORK} può
+ essere specificata insieme a \const{TCP\_NODELAY} soltanto a partire dal
+ kernel 2.5.71.}
+
+\item[\constd{TCP\_MAXSEG}] con questa opzione si legge o si imposta il valore
+ della MSS (\textit{Maximum Segment Size}, vedi sez.~\ref{sec:net_lim_dim} e
+ sez.~\ref{sec:tcp_protocol_xxx}) dei segmenti TCP uscenti. Se l'opzione è
+ impostata prima di stabilire la connessione, si cambia anche il valore della
+ MSS annunciata all'altro capo della connessione. Se si specificano valori
+ maggiori della MTU questi verranno ignorati, inoltre TCP imporrà anche i
+ suoi limiti massimo e minimo per questo valore.
+
+\item[\constd{TCP\_CORK}] questa opzione è il complemento naturale di
+ \const{TCP\_NODELAY} e serve a gestire a livello applicativo la situazione
+ opposta, cioè quella in cui si sa fin dal principio che si dovranno inviare
+ grosse quantità di dati. Anche in questo caso l'\textsl{algoritmo di Nagle}
+ tenderà a suddividerli in dimensioni da lui ritenute
+ opportune,\footnote{l'algoritmo cerca di tenere conto di queste situazioni,
+ ma essendo un algoritmo generico tenderà comunque ad introdurre delle
+ suddivisioni in segmenti diversi, anche quando potrebbero non essere
+ necessarie, con conseguente spreco di banda.} ma sapendo fin dall'inizio
+ quale è la dimensione dei dati si potranno di nuovo ottenere delle migliori
+ prestazioni disabilitandolo, e gestendo direttamente l'invio del nostro
+ blocco di dati in soluzione unica.
+
+ Quando questa opzione viene abilitata non vengono inviati segmenti di dati
+ fintanto che essa non venga disabilitata; a quel punto tutti i dati rimasti
+ in coda saranno inviati in un solo segmento TCP. In sostanza con questa
+ opzione si può controllare il flusso dei dati mettendo una sorta di
+ ``\textsl{tappo}'' (da cui il nome in inglese) al flusso di uscita, in modo
+ ottimizzare a mano l'uso della banda. Si tenga presente che per l'effettivo
+ funzionamento ci si deve ricordare di disattivare l'opzione al termine
+ dell'invio del blocco dei dati.
+
+ Si usa molto spesso \const{TCP\_CORK} quando si effettua il trasferimento
+ diretto di un blocco di dati da un file ad un socket con \func{sendfile}
+ (vedi sez.~\ref{sec:file_sendfile_splice}), per inserire una intestazione
+ prima della chiamata a questa funzione; senza di essa l'intestazione
+ potrebbe venire spedita in un segmento a parte, che a seconda delle
+ condizioni potrebbe richiedere anche una risposta di ACK, portando ad una
+ notevole penalizzazione delle prestazioni.
+
+ Si tenga presente che l'implementazione corrente di \const{TCP\_CORK} non
+ consente di bloccare l'invio dei dati per più di 200 millisecondi, passati i
+ quali i dati accumulati in coda sanno inviati comunque. Questa opzione è
+ tipica di Linux\footnote{l'opzione è stata introdotta con i kernel della
+ serie 2.4.x.} e non è disponibile su tutti i kernel unix-like, pertanto
+ deve essere evitata se si vuole scrivere codice portabile.
+
+\item[\constd{TCP\_KEEPIDLE}] con questa opzione si legge o si imposta
+ l'intervallo di tempo, in secondi, che deve trascorrere senza traffico sul
+ socket prima che vengano inviati, qualora si sia attivata su di esso
+ l'opzione \const{SO\_KEEPALIVE}, i messaggi di \textit{keep-alive} (si veda
+ la trattazione relativa al \textit{keep-alive} in
+ sez.~\ref{sec:sock_options_main}). Anche questa opzione non è disponibile
+ su tutti i kernel unix-like e deve essere evitata se si vuole scrivere
+ codice portabile.
+
+\item[\constd{TCP\_KEEPINTVL}] con questa opzione si legge o si imposta
+ l'intervallo di tempo, in secondi, fra due messaggi di \textit{keep-alive}
+ successivi (si veda sempre quanto illustrato in
+ sez.~\ref{sec:sock_options_main}). Come la precedente non è disponibile su
+ tutti i kernel unix-like e deve essere evitata se si vuole scrivere codice
+ portabile.
+
+\item[\constd{TCP\_KEEPCNT}] con questa opzione si legge o si imposta il numero
+ totale di messaggi di \textit{keep-alive} da inviare prima di concludere che
+ la connessione è caduta per assenza di risposte ad un messaggio di
+ \textit{keep-alive} (di nuovo vedi sez.~\ref{sec:sock_options_main}). Come
+ la precedente non è disponibile su tutti i kernel unix-like e deve essere
+ evitata se si vuole scrivere codice portabile.
+
+\item[\constd{TCP\_SYNCNT}] con questa opzione si legge o si imposta il numero
+ di tentativi di ritrasmissione dei segmenti SYN usati nel \textit{three way
+ handshake} prima che il tentativo di connessione venga abortito (si
+ ricordi quanto accennato in sez.~\ref{sec:TCP_func_connect}). Sovrascrive
+ per il singolo socket il valore globale impostato con la \textit{sysctl}
+ \texttt{tcp\_syn\_retries} (vedi sez.~\ref{sec:sock_ipv4_sysctl}). Non
+ vengono accettati valori maggiori di 255; anche questa opzione non è
+ standard e deve essere evitata se si vuole scrivere codice portabile.
+
+\item[\constd{TCP\_LINGER2}] con questa opzione si legge o si imposta, in
+ numero di secondi, il tempo di sussistenza dei socket terminati nello stato
+ \texttt{FIN\_WAIT2} (si ricordi quanto visto in
+ sez.~\ref{sec:TCP_conn_term}).\footnote{si tenga ben presente che questa
+ opzione non ha nulla a che fare con l'opzione \const{SO\_LINGER} che
+ abbiamo visto in sez.~\ref{sec:sock_options_main}.} Questa opzione
+ consente di sovrascrivere per il singolo socket il valore globale impostato
+ con la \textit{sysctl} \texttt{tcp\_fin\_timeout} (vedi
+ sez.~\ref{sec:sock_ipv4_sysctl}). Anche questa opzione è da evitare se si
+ ha a cuore la portabilità del codice.
+
+\item[\constd{TCP\_DEFER\_ACCEPT}] questa opzione consente di modificare il
+ comportamento standard del protocollo TCP nello stabilirsi di una
+ connessione; se ricordiamo il meccanismo del \textit{three way handshake}
+ illustrato in fig.~\ref{fig:TCP_TWH} possiamo vedere che in genere un client
+ inizierà ad inviare i dati ad un server solo dopo l'emissione dell'ultimo
+ segmento di ACK.
+
+ Di nuovo esistono situazioni (e la più tipica è quella di una richiesta
+ HTTP) in cui sarebbe utile inviare immediatamente la richiesta all'interno
+ del segmento con l'ultimo ACK del \textit{three way handshake}; si potrebbe
+ così risparmiare l'invio di un segmento successivo per la richiesta e il
+ ritardo sul server fra la ricezione dell'ACK e quello della richiesta.
+
+ Se si invoca \const{TCP\_DEFER\_ACCEPT} su un socket dal lato client (cioè
+ dal lato da cui si invoca \func{connect}) si istruisce il kernel a non
+ inviare immediatamente l'ACK finale del \textit{three way handshake},
+ attendendo per un po' di tempo la prima scrittura, in modo da inviare i dati
+ di questa insieme col segmento ACK. Chiaramente la correttezza di questo
+ comportamento dipende in maniera diretta dal tipo di applicazione che usa il
+ socket; con HTTP, che invia una breve richiesta, permette di risparmiare un
+ segmento, con FTP, in cui invece si attende la ricezione del prompt del
+ server, introduce un inutile ritardo.
+
+ Allo stesso tempo il protocollo TCP prevede che sul lato del server la
+ funzione \func{accept} ritorni dopo la ricezione dell'ACK finale, in tal
+ caso quello che si fa usualmente è lanciare un nuovo processo per leggere i
+ successivi dati, che si bloccherà su una \func{read} se questi non sono
+ disponibili; in questo modo si saranno impiegate delle risorse (per la
+ creazione del nuovo processo) che non vengono usate immediatamente. L'uso
+ di \const{TCP\_DEFER\_ACCEPT} consente di intervenire anche in questa
+ situazione; quando la si invoca sul lato server (vale a dire su un socket in
+ ascolto) l'opzione fa sì che \func{accept} ritorni soltanto quando sono
+ presenti dei dati sul socket, e non alla ricezione dell'ACK conclusivo del
+ \textit{three way handshake}.
+
+ L'opzione prende un valore intero che indica il numero massimo di secondi
+ per cui mantenere il ritardo, sia per quanto riguarda il ritorno di
+ \func{accept} su un server, che per l'invio dell'ACK finale insieme ai dati
+ su un client. L'opzione è specifica di Linux non deve essere utilizzata in
+ codice che vuole essere portabile.\footnote{su FreeBSD è presente una
+ opzione \texttt{SO\_ACCEPTFILTER} che consente di ottenere lo stesso
+ comportamento di \const{TCP\_DEFER\_ACCEPT} per quanto riguarda il lato
+ server.}
+
+\item[\constd{TCP\_WINDOW\_CLAMP}] con questa opzione si legge o si imposta
+ alla dimensione specificata, in byte, il valore dichiarato della
+ \textit{advertised window} (vedi sez.~\ref{sec:tcp_protocol_xxx}). Il kernel
+ impone comunque una dimensione minima pari a \texttt{SOCK\_MIN\_RCVBUF/2}.
+ Questa opzione non deve essere utilizzata in codice che vuole essere
+ portabile.
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{0.80\textwidth}
+ \includestruct{listati/tcp_info.h}
+ \end{minipage}
+ \caption{La struttura \structd{tcp\_info} contenente le informazioni sul
+ socket restituita dall'opzione \const{TCP\_INFO}.}
+ \label{fig:tcp_info_struct}
+\end{figure}
+
+\item[\constd{TCP\_INFO}] questa opzione, specifica di Linux, ma introdotta
+ anche in altri kernel (ad esempio FreeBSD) permette di controllare lo stato
+ interno di un socket TCP direttamente da un programma in \textit{user space}.
+ L'opzione restituisce in una speciale struttura \struct{tcp\_info}, la cui
+ definizione è riportata in fig.~\ref{fig:tcp_info_struct}, tutta una serie
+ di dati che il kernel mantiene, relativi al socket. Anche questa opzione
+ deve essere evitata se si vuole scrivere codice portabile.
+
+ Con questa opzione diventa possibile ricevere una serie di informazioni
+ relative ad un socket TCP così da poter effettuare dei controlli senza dover
+ passare attraverso delle operazioni di lettura. Ad esempio si può verificare
+ se un socket è stato chiuso usando una funzione analoga a quella illustrata
+ in fig.~\ref{fig:is_closing}, in cui si utilizza il valore del campo
+ \var{tcpi\_state} di \struct{tcp\_info} per controllare lo stato del socket.
+
+\begin{figure}[!htbp]
+ \footnotesize \centering
+ \begin{minipage}[c]{\codesamplewidth}
+ \includecodesample{listati/is_closing.c}
+ \end{minipage}
+ \caption{Codice della funzione \texttt{is\_closing.c}, che controlla lo stato
+ di un socket TCP per verificare se si sta chiudendo.}
+ \label{fig:is_closing}
+\end{figure}
+
+%Si noti come nell'esempio si sia (
+
+
+\item[\constd{TCP\_QUICKACK}] con questa opzione è possibile eseguire una forma
+ di controllo sull'invio dei segmenti ACK all'interno di in flusso di dati su
+ TCP. In genere questo invio viene gestito direttamente dal kernel, il
+ comportamento standard, corrispondente la valore logico di vero (in genere
+ 1) per questa opzione, è quello di inviare immediatamente i segmenti ACK, in
+ quanto normalmente questo significa che si è ricevuto un blocco di dati e si
+ può passare all'elaborazione del blocco successivo.
+
+ Qualora però la nostra applicazione sappia in anticipo che alla ricezione di
+ un blocco di dati seguirà immediatamente l'invio di un altro
+ blocco,\footnote{caso tipico ad esempio delle risposte alle richieste HTTP.}
+ poter accorpare quest'ultimo al segmento ACK permette di risparmiare sia in
+ termini di dati inviati che di velocità di risposta. Per far questo si può
+ utilizzare \const{TCP\_QUICKACK} impostando un valore logico falso (cioè 0),
+ in questo modo il kernel attenderà così da inviare il prossimo segmento di
+ ACK insieme ai primi dati disponibili.
+
+ Si tenga presente che l'opzione non è permanente, vale a dire che una volta
+ che la si sia impostata a 0 il kernel la riporterà al valore di default dopo
+ il suo primo utilizzo. Sul lato server la si può impostare anche una volta
+ sola su un socket in ascolto, ed essa verrà ereditata da tutti i socket che
+ si otterranno da esso al ritorno di \func{accept}.
+
+% TODO trattare con gli esempi di apache
+
+\item[\constd{TCP\_CONGESTION}] questa opzione permette di impostare quale
+ algoritmo per il controllo della congestione\footnote{il controllo della
+ congestione è un meccanismo previsto dal protocollo TCP (vedi
+ sez.~\ref{sec:tcp_protocol_xxx}) per evitare di trasmettere inutilmente
+ dati quando una connessione è congestionata; un buon algoritmo è
+ fondamentale per il funzionamento del protocollo, dato che i pacchetti
+ persi andrebbero ritrasmessi, per cui inviare un pacchetto su una linea
+ congestionata potrebbe causare facilmente un peggioramento della
+ situazione.} utilizzare per il singolo socket. L'opzione è stata
+ introdotta con il kernel 2.6.13,\footnote{alla data di stesura di queste
+ note (Set. 2006) è pure scarsamente documentata, tanto che non è neanche
+ definita nelle intestazioni della \acr{glibc} per cui occorre definirla a
+ mano al suo valore che è 13.} e prende come per \param{optval} il
+ puntatore ad un buffer contenente il nome dell'algoritmo di controllo che
+ si vuole usare.
+
+ L'uso di un nome anziché di un valore numerico è dovuto al fatto che gli
+ algoritmi di controllo della congestione sono realizzati attraverso
+ altrettanti moduli del kernel, e possono pertanto essere attivati a
+ richiesta; il nome consente di caricare il rispettivo modulo e di introdurre
+ moduli aggiuntivi che implementino altri meccanismi.
+
+ Per poter disporre di questa funzionalità occorre aver compilato il kernel
+ attivando l'opzione di configurazione generale
+ \texttt{TCP\_CONG\_ADVANCED},\footnote{disponibile come \textit{TCP:
+ advanced congestion control} nel menù \textit{Network->Networking
+ options}, che a sua volta renderà disponibile un ulteriore menù con gli
+ algoritmi presenti.} e poi abilitare i singoli moduli voluti con le varie
+ \texttt{TCP\_CONG\_*} presenti per i vari algoritmi disponibili; un elenco
+ di quelli attualmente supportati nella versione ufficiale del kernel è
+ riportato in tab.~\ref{tab:sock_tcp_congestion_algo}.\footnote{la lista è
+ presa dalla versione 2.6.17.}
+
+
+ Si tenga presente che prima della implementazione modulare alcuni di questi
+ algoritmi erano disponibili soltanto come caratteristiche generali del
+ sistema, attivabili per tutti i socket, questo è ancora possibile con la
+ \textit{sysctl} \texttt{tcp\_congestion\_control} (vedi
+ sez.~\ref{sec:sock_ipv4_sysctl}) che ha sostituito le precedenti
+ \textit{sysctl}.\footnote{riportate anche, alla data di stesura di queste
+ pagine (Set. 2006) nelle pagine di manuale, ma non più presenti.}
+
+ \begin{table}[!htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|l|l|}
+ \hline
+ \textbf{Nome}&\textbf{Configurazione}&\textbf{Riferimento} \\
+ \hline
+ \hline
+ reno& -- &Algoritmo tradizionale, usato in caso di assenza degli altri.\\
+ \texttt{bic} &\texttt{TCP\_CONG\_BIC} &
+ \url{http://www.csc.ncsu.edu/faculty/rhee/export/bitcp/index.htm}.\\
+ \texttt{cubic} &\texttt{TCP\_CONG\_CUBIC} &
+ \url{http://www.csc.ncsu.edu/faculty/rhee/export/bitcp/index.htm}.\\
+ \texttt{highspeed}&\texttt{TCP\_CONG\_HSTCP} &
+ \url{http://www.icir.org/floyd/hstcp.html}.\\
+ \texttt{htcp} &\texttt{TCP\_CONG\_HTCP} &
+ \url{http://www.hamilton.ie/net/htcp/}.\\
+ \texttt{hybla} &\texttt{TCP\_CONG\_HYBLA} &
+ \url{http://www.danielinux.net/projects.html}.\\
+ \texttt{scalable}&\texttt{TCP\_CONG\_SCALABLE}&
+ \url{http://www.deneholme.net/tom/scalable/}.\\
+ \texttt{vegas} &\texttt{TCP\_CONG\_VEGAS} &
+ \url{http://www.cs.arizona.edu/protocols/}.\\
+ \texttt{westwood}&\texttt{TCP\_CONG\_WESTWOOD}&
+ \url{http://www.cs.ucla.edu/NRL/hpi/tcpw/}.\\
+% \texttt{}&\texttt{}& .\\
+ \hline
+ \end{tabular}
+ \caption{Gli algoritmi per il controllo della congestione disponibili con
+ Linux con le relative opzioni di configurazione da attivare.}
+ \label{tab:sock_tcp_congestion_algo}
+ \end{table}