\func{select} che ritorna a causa dello stesso.
\end{basedescript}
+% TODO documentare SO_ATTACH_FILTER e SO_DETACH_FILTER
+
\subsection{L'uso delle principali opzioni dei socket}
\label{sec:sock_options_main}
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
+ 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
+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
\begin{table}[!htb]
\centering
\footnotesize
- \begin{tabular}[c]{|l|c|c|c|l|p{7cm}|}
+ \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.\\
+ spedisce immediatamente i dati in segmenti singoli.\\
\const{TCP\_MAXSEG} &$\bullet$&$\bullet$& &\texttt{int}&
- valore della \itindex{Maximum~Segment~Size} MSS per i pacchetti in
+ valore della \itindex{Maximum~Segment~Size} MSS per i segmenti in
uscita.\\
\const{TCP\_CORK} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
- non invia frame parziali.\\
+ 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}&
\const{TCP\_KEEPCNT} &$\bullet$&$\bullet$& &\texttt{int}&
numero massimo di \textit{keepalive} inviati.\\
\const{TCP\_SYNCNT} &$\bullet$&$\bullet$& &\texttt{int}&
- numero massimo di ritrasmissioni del pacchetto SYN.\\
+ 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}.\\
+ valore della \itindex{advertised~window} \textit{advertised window}.\\
\const{TCP\_INFO} &$\bullet$& & &\struct{tcp\_info}&
- raccoglie informazioni sul socket.\\
+ restituisce informazioni sul socket.\\
\const{TCP\_QUICKACK} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
abilita la modalità \textit{quickack}.\\
\const{TCP\_CONGESTION} &$\bullet$&$\bullet$&? &\texttt{?}& %???
\end{table}
Le descrizioni delle varie opzioni riportate in
-tab.~\ref{tab:sock_opt_tcplevel} sono estremamente sintetiche, una maggiore
-quantità di dettagli e la spiegazione delle singole opzioni è fornita nel
-seguente elenco:
+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 prevede, per evitare la
- trasmissione di tanti pacchetti piccoli, che comporta un utilizzo non
- ottimale della banda disponibile, un meccanismo di bufferizzazione dei
- pacchetti uscenti controllato da un apposito algoritmo (detto
- \textsl{algoritmo di Nagle}, vedi sez.\ref{sez:tcp_protocol_xxx}). Il
- comportamento normale prevede invece 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 \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
+\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}] permette di leggere e modificare il valore della
- \itindex{Maximum~Segment~Size} MSS dei pacchetti uscenti, e se l'opzione è
- impostata prima di stabilire la connessione, 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[\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 direttamente il flusso dei dati
- mettendo un ``\textsl{tappo}'' al flusso di uscita, in modo ottimizzare a
- mano il throughput. È 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.
+\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 pacchetti per più di 200 millisecondi,
- passati i quali i dati accumulati in cosa 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
+ 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\_KEEPCNT}] imposta il numero totale di messaggi di
- \textit{keep-alive} da inviare prima di concludere che la connessione è
- caduta (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 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 il valore globale impostato con la
- \textit{sysctl} \texttt{tcp\_fin\_timeout} (vedi
+\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}] 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
+\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 utile 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 fa 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\_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
+\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
\end{figure}
Con questa opzione diventa possibile ricevere una serie di informazioni
-relative al socket così da poter effettuare dei controlli, senza passare
-attraverso delle operazioni di lettura. Ad esempio si può verificare se un
-socket è stato chiuso con una funzione analoga a quella illustrata in
-fig.~\ref{fig:is_closing}, in cui si usa il campo \var{tcpi\_state} di
-\struct{tcp\_info} per controllare lo stato del socket.
+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
\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).
-
-\item[\const{TCP\_CONGESTION}] Introdotta con il kernel 2.6.13, non è
- documentata.
+\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}
caratteristiche delle opzioni citate è quello dell'elenco seguente:
\begin{basedescript}{\desclabelwidth{2.5cm}\desclabelstyle{\nextlinelabel}}
-\item[\const{UDP\_CORK}] Introdotta con il kernel 2.5.44
+\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}] Introdotta con il kernel 2.5.67.
+\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}
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 dal tipo o famiglia dello stesso, e permette
-di impostare e rilevare le funzionalità delle interfacce di rete.
+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
dell'interfaccia, e restituisce il relativo nome in \var{ifr\_name}.
Il kernel infatti assegna ad ogni interfaccia un numero progressivo, detto
- appunto \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}.
+ 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. Il valore restituito
- è una maschera binaria i cui bit sono identificabili attraverso le varie
- costanti di tab.~\ref{tab:netdevice_iface_flag}.
+ 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
\item[\const{SIOCSIFFLAGS}] permette di impostare il valore dei flag
- dell'interfaccia attraverso il valore della maschera binaria da passare nel
+ 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}] .
-\item[\const{SIOCSIFMETRIC}] .
-\item[\const{SIOCGIFMTU}] .
-\item[\const{SIOCSIFMTU}] .
-\item[\const{SIOCGIFHWADDR}] .
-\item[\const{SIOCSIFHWADDR}] .
-\item[\const{SIOCSIFHWBROADCAST}] .
-\item[\const{SIOCGIFMAP}] .
-\item[\const{SIOCSIFMAP}] .
-\item[\const{SIOCADDMULTI}] .
-\item[\const{SIOCDELMULTI}] .
-\item[\const{SIOCGIFTXQLEN}] .
-\item[\const{SIOCSIFTXQLEN}] .
-\item[\const{SIOCSIFNAME}] .
-\item[\const{SIOCGIFCONF}] .
+\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}
\end{basedescript}
+%%% Local Variables:
+%%% mode: latex
+%%% TeX-master: "gapil"
+%%% End:
+
+
% LocalWords: socket sez dotted decimal resolver Domain Name Service cap DNS
% LocalWords: client fig LDAP Lightweight Access Protocol NIS Information Sun
% LocalWords: rmem wmem message cost burst bucket filter netdev backlog optmem
% LocalWords: forward dynaddr dial autoconfig local masquerading ipfrag high
% LocalWords: thresh low always defrag CONFIG SETSIG cmd FIOGETOWN FIOSETOWN
-
-%%% Local Variables:
-%%% mode: latex
-%%% TeX-master: "gapil"
-%%% End:
% LocalWords: quest'ultime neigh dev weight cong mod somaxconn Di SIOCINQ DoS
% LocalWords: Documentation SIOCATMARK SIOCOUTQ FIONREAD TIOCOUTQ Denial work
% LocalWords: netfilter scheduler mark ARP DHCP BOOTP RARP nonlocal sniffer is
% LocalWords: abort overflow adv win app bic convergence dsack ecn fack frto
% LocalWords: intvl probes latency orphans l'ACK SYNQ HSIZE tw buckets mem rfc
% LocalWords: orphan reordering collapse sack stdurg synack syncookies recycle
-% LocalWords: timestamps scaling vegas avoid westwood
+% LocalWords: timestamps scaling vegas avoid westwood tcpi l'incapsulazione
+% LocalWords: metric EOPNOTSUPP mtu hwaddr ARPHRD interrupt DMA map qlen silly
+% LocalWords: rename ifconf syndrome dell'ACK FTP ACCEPTFILTER