\item[\const{SO\_SNDBUF}] questa opzione imposta la dimensione del buffer di
uscita del socket. Prende per \param{optval} un intero indicante il numero
- di byte. Il valore di default ed il valore massimo che si può specificare
- come argomento per questa opzione sono impostabili tramiti gli opportuni
- valori di \func{sysctl} (vedi sez.~\ref{sec:sock_sysctl}).
+ di byte. Il valore di default ed il valore massimo che si possono
+ specificare come argomento per questa opzione sono impostabili
+ rispettivamente tramite gli opportuni valori di \func{sysctl} (vedi
+ sez.~\ref{sec:sock_sysctl}).
\item[\const{SO\_RCVBUF}] questa opzione imposta la dimensione del buffer di
ingresso del socket. Prende per \param{optval} un intero indicante il numero
come argomento per questa opzione sono impostabili tramiti gli opportuni
valori di \func{sysctl} (vedi sez.~\ref{sec:sock_sysctl}).
+ Si tenga presente che nel caso di socket TCP, per entrambe le opzioni
+ \const{SO\_RCVBUF} e \const{SO\_SNDBUF}, il kernel alloca effettivamente una
+ quantità di memoria doppia rispetto a quanto richiesto con
+ \func{setsockopt}. Questo comporta che una successiva lettura con
+ \func{getsockopt} riporterà un valore diverso da quello impostato con
+ \func{setsockopt}. Questo avviene perché TCP necessita dello spazio in più
+ per mantenere dati amministrativi e strutture interne, e solo una parte
+ viene usata come buffer per i dati, mentre il valore letto da
+ \func{getsockopt} e quello riportato nei vari parametri di
+ \textit{sysctl}\footnote{cioè \texttt{wmem\_max} e \texttt{rmem\_max} in
+ \texttt{/proc/sys/net/core} e \texttt{tcp\_wmem} e \texttt{tcp\_rmem} in
+ \texttt{/proc/sys/net/ipv4}, vedi sez.~\ref{sec:sock_sysctl}.} indica la
+ memoria effettivamente impiegata. Si tenga presente inoltre che le
+ modifiche alle dimensioni dei buffer di ingresso e di uscita per poter
+ essere effettive devono essere impostate prima della chiamata alle funzioni
+ \func{listen} o \func{connect}.
+
\item[\const{SO\_LINGER}] questa opzione controlla le modalità con cui viene
chiuso un socket quando si utilizza un protocollo che supporta le
connessioni (è pertanto usata con i socket TCP ed ignorata per UDP) e
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,
-questo può comportare che un crollo della connessione, qualora avvenisse ad
-esempio in conseguenza di una interruzione completa della rete, potrebbe
-passare inosservato.
+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 socket che supportino
+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
+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.
-In caso di problemi invece si possono avere i due casi già illustrati in
-sez.~\ref{sec:TCP_conn_crash} per il caso di terminazione precoce del server:
-il primo è quello in cui la macchina remota è caduta ed è stata riavviata, per
-cui dopo il riavvio la connessione non viene più riconosciuta,\footnote{si
- ricordi che un normale riavvio non ha questo effetto, in quanto in tal caso
- si passa per la chiusura del processo, e questo, come illustrato in
- sez.~\ref{sec:file_close}, comporta la chiusura del socket con l'invio di un
- segmento FIN all'altro capo della connessione, che verrà regolarmente
- chiusa.} 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. In tal caso il socket viene
-chiuso dopo aver impostato un errore \errcode{ECONNRESET}.
+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 riportanto 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 opportunamente modificati con gli opportuni parametri illustrati in
- sez.~\ref{sec:sock_sysctl}, si tenga presente che però questo vale a livello
- di kernel ed i suddetti valori saranno applicati a \textsl{tutti} i socket.}
-(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 invece si riceve come risposta un pacchetto ICMP di
-destinazione irraggiungibile (vedi sez.~\ref{sec:icmp_protocol_xxx}), verrà
-restituito l'errore corrispondente.
+ essere opportunamente 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 invece 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
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 perché o
-il client sull'altro capo non è più attivo o non è più in grado di comunicare
-con il server via rete.
+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
numero massimo di ritrasmissioni del pacchetto SYN.\\
\const{TCP\_LINGER2} &$\bullet$&$\bullet$& &\texttt{int}&
tempo di vita in stato \texttt{FIN\_WAIT2}.\\
- \const{TCP\_DEFER\_ACCEPT}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ \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}&
+ \const{TCP\_INFO} &$\bullet$& & &\struct{tcp\_info}&
raccoglie informazioni sul socket.\\
\const{TCP\_QUICKACK} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
abilita la modalità \textit{quickack}.\\
\label{tab:sock_opt_tcplevel}
\end{table}
-Le descrizioni riportata 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:
-\begin{basedescript}{\desclabelwidth{3.0cm}\desclabelstyle{\nextlinelabel}}
+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:
+\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
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.
-
- Questa opzione non è disponibile su tutti i kernel unix-like e deve essere
- evitata se si vuole avere codice portabile.
-
-\item[\const{TCP\_KEEPINTVL}]
-
-\item[\const{TCP\_KEEPCNT}]
-
-\item[\const{TCP\_SYNCNT}]
-
-\item[\const{TCP\_LINGER2}]
+ 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.
+
+ 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
+ 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 la
+ \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
+ 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}] permette di ricevere una serie di informazioni
+ relative al socket che il kernel restituisce in una speciale struttura
+ \struct{tcp\_info}, la cui definizione è riportata in
+ fig.~\ref{fig:tcp_info_struct}.
-\item[\const{TCP\_DEFER\_ACCEPT}]
-
-\item[\const{TCP\_WINDOW\_CLAMP}]
-
-\item[\const{TCP\_INFO}]
+\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}
-\item[\const{TCP\_QUICKACK}]
+\item[\const{TCP\_QUICKACK}] abilita la modalità speciale \textit{quickack}.
\item[\const{TCP\_CONGESTION}] Introdotta con il kernel 2.6.13.
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 validi per tutti i socket. Quelli
-descritti anche nella pagina di manuale, accessibile con \texttt{man 7 socket}
-sono i seguenti:
+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
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.2cm}\desclabelstyle{\nextlinelabel}}
+\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ò
% \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}$, e
+ 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}