+\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 tutti i pacchetti il prima possibile.\\
+ \const{TCP\_MAXSEG} &$\bullet$&$\bullet$& &\texttt{int}&
+ valore della \itindex{Maximum~Segment~Size} MSS per i pacchetti in
+ uscita.\\
+ \const{TCP\_CORK} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ non invia frame parziali.\\
+ \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 un meccanismo di bufferizzazione
+ dei pacchetti uscenti, per evitare la trasmissione di tanti pacchetti
+ piccoli con un utilizzo non ottimale della banda disponibile. 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 pacchetti siano accumulati fintanto che non si
+ raggiunge una quantità di dati considerata adeguata per eseguire la
+ trasmissione.
+
+ Impostando questa opzione si disabilita questo meccanismo ed i pacchetti
+ vengono inviati immediatamente qualunque sia la loro dimensione; l'opzione
+ viene sovrascritta dall'eventuale impostazione dell'opzione
+ \const{TCP\_CORK}, 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 pacchetti 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}] permette di leggere e modificare il valore della
+ \itindex{Maximum~Segment~Size} MSS (vedi sez.~\ref{sec:net_lim_dim} e
+ sez.\ref{sez:tcp_protocol_xxx}) dei pacchetti uscenti, e se l'opzione è
+ impostata prima di stabilire la connessione, 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}] quando questa opzione viene abilitata non vengono
+ inviati pacchetti di dati fintanto che essa non venga disabilitata; a quel
+ punto tutti i dati rimasti in coda saranno inviati in un solo pacchetto.
+ Questa opzione viene usata per gestire manualmente 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. È molto
+ utile anche quando si effettua il trasferimento di dati da un file con
+ \func{sendfile} (vedi sez.~\ref{sec:file_sendfile}), se si vuole inserire
+ una intestazione prima della chiamata a questa funzione.
+
+ Si tenga presente che l'implementazione corrente di \const{TCP\_CORK} non
+ consente di bloccare l'invio dei pacchetti per più di 200 millisecondi,
+ passati i quali i dati accumulati in coda sanno inviati comunque. Questa
+ opzione non è disponibile su tutti i kernel unix-like e deve essere evitata
+ se si vuole scrivere codice portabile.
+
+\item[\const{TCP\_KEEPIDLE}] 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}] 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}] 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}] 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}] 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}] consente ad un socket in ascolto di
+ ritornare da \func{accept} soltanto quando sono presenti dati sullo stesso,
+ e non alla conclusione del \itindex{three~way~handshake} \textit{three way
+ handshake}. Prende un valore intero che indica il numero massimo di
+ secondi per cui il ritorno di \func{accept} viene rimandato; non deve essere
+ utilizzata in codice che vuole essere portabile.
+
+\item[\const{TCP\_WINDOW\_CLAMP}] limita 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}] opzione, specifica di Linux, ma introdotta anche in
+ altri kernel (ad esempio FreeBSD) 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}] abilita o disabilita la modalità speciale
+ \textit{quickack}, in cui i pacchetti ACK vengono inviati immediatamente
+ senza le attese talvolta imposte dal normale funzionamento del protocollo
+ TCP. Questa opzione prende un valore logico, e non è permanente, nel senso
+ che si limita a forzare al momento della chiamata un passaggio da o verso la
+ modalità \textit{quickack}; le operazioni successive potrebbero a loro volta
+ entrare o uscire da questa modalità a seconda del processo interno del
+ protocollo o dalle condizioni della connessione (ad esempio in presenza di
+ timeout ritardati per i pacchetti ACK).
+
+% 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}
+
+
+
+