Documentate quasi tutte le opzioni dei socket TCP ed alcune sysctl
authorSimone Piccardi <piccardi@gnulinux.it>
Fri, 8 Sep 2006 17:21:17 +0000 (17:21 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Fri, 8 Sep 2006 17:21:17 +0000 (17:21 +0000)
correlate, messi vari riferimenti rimasti indietro nei capitoli precedenti.

fileadv.tex
listati/tcp_info.h [new file with mode: 0644]
network.tex
sockctrl.tex
tcpsock.tex
trasplayer.tex

index 29e78d9f1ea97580395a9f68ccb6aece2b6289b3..5717640eb5b19b4ce01a65f434e5c4ce2c7ea65a 100644 (file)
@@ -1836,6 +1836,19 @@ mappatura che gi
 \itindend{memory~mapping}
 
 
+\subsection{L'I/O diretto fra file descriptor con \func{sendfile}}
+\label{sec:file_sendfile}
+
+Uno dei problemi 
+
+NdA è da finire, sul perché non è abilitata fra file vedi:
+
+\href{http://www.cs.helsinki.fi/linux/linux-kernel/2001-03/0200.html}
+{\texttt{http://www.cs.helsinki.fi/linux/linux-kernel/2001-03/0200.html}}
+% TODO documentare la funzione sendfile
+
+
+
 % i raw device 
 %\subsection{I \textit{raw} device}
 %\label{sec:file_raw_device}
@@ -1849,11 +1862,6 @@ mappatura che gi
 % TODO l'I/O sulle porte di I/O 
 % consultare le manpage di ioperm, iopl e outb
 
-%\subsection{L'I/O diretto fra file descriptor con \func{sendfile}}
-%\label{sec:file_sendfile}
-%
-% TODO documentare la funzione sendfile
-% consultare la manpage di sendfile
 
 
 
diff --git a/listati/tcp_info.h b/listati/tcp_info.h
new file mode 100644 (file)
index 0000000..db03af1
--- /dev/null
@@ -0,0 +1,37 @@
+struct tcp_info
+{
+  u_int8_t      tcpi_state;
+  u_int8_t      tcpi_ca_state;
+  u_int8_t      tcpi_retransmits;
+  u_int8_t      tcpi_probes;
+  u_int8_t      tcpi_backoff;
+  u_int8_t      tcpi_options;
+  u_int8_t      tcpi_snd_wscale : 4, tcpi_rcv_wscale : 4;
+
+  u_int32_t     tcpi_rto;
+  u_int32_t     tcpi_ato;
+  u_int32_t     tcpi_snd_mss;
+  u_int32_t     tcpi_rcv_mss;
+
+  u_int32_t     tcpi_unacked;
+  u_int32_t     tcpi_sacked;
+  u_int32_t     tcpi_lost;
+  u_int32_t     tcpi_retrans;
+  u_int32_t     tcpi_fackets;
+
+  /* Times. */
+  u_int32_t     tcpi_last_data_sent;
+  u_int32_t     tcpi_last_ack_sent;     /* Not remembered, sorry.  */
+  u_int32_t     tcpi_last_data_recv;
+  u_int32_t     tcpi_last_ack_recv;
+
+  /* Metrics. */
+  u_int32_t     tcpi_pmtu;
+  u_int32_t     tcpi_rcv_ssthresh;
+  u_int32_t     tcpi_rtt;
+  u_int32_t     tcpi_rttvar;
+  u_int32_t     tcpi_snd_ssthresh;
+  u_int32_t     tcpi_snd_cwnd;
+  u_int32_t     tcpi_advmss;
+  u_int32_t     tcpi_reordering;
+};
index c96d96b402fa9b0d26fc1c870f5ffa5186b66fb8..e7859a0395b3afe27e33eff89df2a07c7398c7f3 100644 (file)
@@ -663,10 +663,10 @@ scartare i duplicati.
 
 Il protocollo provvede anche un controllo di flusso (\textit{flow control}),
 cioè specifica sempre all'altro capo della trasmissione quanti dati può
-ricevere tramite una \textit{advertised window} (letteralmente
-\textsl{finestra annunciata)}, che indica lo spazio disponibile nel buffer di
-ricezione, cosicché nella trasmissione non vengano inviati più dati di quelli
-che possono essere ricevuti.
+ricevere tramite una \itindex{advertised~window} \textit{advertised window}
+(letteralmente ``\textsl{finestra annunciata}''), che indica lo spazio
+disponibile nel buffer di ricezione, cosicché nella trasmissione non vengano
+inviati più dati di quelli che possono essere ricevuti.
 
 Questa finestra cambia dinamicamente diminuendo con la ricezione dei dati dal
 socket ed aumentando con la lettura di quest'ultimo da parte
index 18cada6e51c6bb9b0a4e9faffa384ac59eba370c..f90a45eb5cff9fff18e7f2aef8e1f99e7816b5b9 100644 (file)
@@ -2239,9 +2239,10 @@ tab.~\ref{tab:sock_opt_socklevel} sul significato delle varie opzioni:
 
 \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
@@ -2249,6 +2250,23 @@ tab.~\ref{tab:sock_opt_socklevel} sul significato delle varie opzioni:
   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
@@ -2298,52 +2316,53 @@ approfondimento sul significato delle opzioni generiche pi
 
 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
@@ -2351,9 +2370,9 @@ principalmente sui server per evitare di mantenere impegnate le risorse che
 verrebbero dedicate a trattare delle connessioni che in realtà sono già
 terminate (quelle che vengono anche chiamate connessioni
 \textsl{semi-aperte}); in tutti quei casi cioè in cui il server si trova in
-attesa di dati in ingresso su una connessione che non arriveranno mai 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
@@ -3048,11 +3067,11 @@ accessibili includendo detto file.\footnote{in realt
       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}.\\
@@ -3065,10 +3084,11 @@ accessibili includendo detto file.\footnote{in realt
   \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
@@ -3101,26 +3121,85 @@ opzioni 
   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.
 
@@ -3505,14 +3584,13 @@ sistema sotto \texttt{/proc/net}, dove sono presenti dei file che non
 corrispondono a nessun nodo di \func{sysctl}.
 
 
-
 \subsection{I valori di controllo per i socket generici}
 \label{sec:sock_gen_sysctl}
 
 Nella directory \texttt{/proc/sys/net/core} sono presenti i file
-corrispondenti ai parametri generici 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
@@ -3605,7 +3683,7 @@ dello stesso (come ARP).
 I file che consentono di controllare le caratteristiche specifiche del
 protocollo IP in quanto tale, descritti anche nella pagina di manuale
 accessibile con \texttt{man 7 ip}, sono i seguenti:
-\begin{basedescript}{\desclabelwidth{3.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ò
@@ -3666,9 +3744,89 @@ accessibile con \texttt{man 7 ip}, sono i seguenti:
 
 % \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}
 
 
 
index a241b60525479b9d89225f3fa3129b152bebc7d2..7316b64b3f274b7a3af14125b42fe7d9ffc31eb6 100644 (file)
@@ -136,28 +136,28 @@ regolare la connessione. Normalmente vengono usate le seguenti opzioni:
   connessione annuncia all'altro il massimo ammontare di dati che vorrebbe
   accettare per ciascun segmento nella connessione corrente. È possibile
   leggere e scrivere questo valore attraverso l'opzione del socket
-  \const{TCP\_MAXSEG}.
+  \const{TCP\_MAXSEG} (vedi sez.~\ref{sec:TCP_TCP_opt}).
   
-\item \textit{window scale
-    option}, %come spiegato in sez.~\ref{sec:tcp_protocol}
-  il protocollo TCP implementa il controllo di flusso attraverso una
-  \textsl{finestra annunciata} (\textit{advertized window}) con la quale
-  ciascun capo della comunicazione dichiara quanto spazio disponibile ha in
-  memoria per i dati. Questo è un numero a 16 bit dell'header, che così può
-  indicare un massimo di 65535 byte;\footnote{ Linux usa come massimo 32767
-    per evitare problemi con alcune implementazioni che usano l'aritmetica con
-    segno per implementare lo stack TCP.} ma alcuni tipi di connessione come
-  quelle ad alta velocità (sopra i 45Mbit/sec) e quelle che hanno grandi
-  ritardi nel cammino dei pacchetti (come i satelliti) richiedono una finestra
-  più grande per poter ottenere il massimo dalla trasmissione, per questo
-  esiste questa opzione che indica un fattore di scala da applicare al valore
-  della finestra annunciata\footnote{essendo una nuova opzione per garantire
-    la compatibilità con delle vecchie implementazioni del protocollo la
-    procedura che la attiva prevede come negoziazione che l'altro capo della
-    connessione riconosca esplicitamente l'opzione inserendola anche lui nel
-    suo SYN di risposta dell'apertura della connessione.} per la connessione
-  corrente (espresso come numero di bit cui spostare a sinistra il valore
-  della finestra annunciata inserito nel pacchetto).
+\item \textit{window scale option}, il protocollo TCP implementa il controllo
+  di flusso attraverso una \itindex{advertised~window} \textit{advertised
+    window} (la ``\textsl{finestra annunciata}'', vedi
+  sez.~\ref{sec:tcp_protocol_xxx}) con la quale ciascun capo della
+  comunicazione dichiara quanto spazio disponibile ha in memoria per i dati.
+  Questo è un numero a 16 bit dell'header, che così può indicare un massimo di
+  65535 byte;\footnote{ Linux usa come massimo 32767 per evitare problemi con
+    alcune implementazioni che usano l'aritmetica con segno per implementare
+    lo stack TCP.} ma alcuni tipi di connessione come quelle ad alta velocità
+  (sopra i 45Mbit/sec) e quelle che hanno grandi ritardi nel cammino dei
+  pacchetti (come i satelliti) richiedono una finestra più grande per poter
+  ottenere il massimo dalla trasmissione, per questo esiste questa opzione che
+  indica un fattore di scala da applicare al valore della finestra
+  annunciata\footnote{essendo una nuova opzione per garantire la compatibilità
+    con delle vecchie implementazioni del protocollo la procedura che la
+    attiva prevede come negoziazione che l'altro capo della connessione
+    riconosca esplicitamente l'opzione inserendola anche lui nel suo SYN di
+    risposta dell'apertura della connessione.} per la connessione corrente
+  (espresso come numero di bit cui spostare a sinistra il valore della
+  finestra annunciata inserito nel pacchetto).
 
 \item \textit{timestamp option}, è anche questa una nuova opzione necessaria
   per le connessioni ad alta velocità per evitare possibili corruzioni di dati
@@ -759,7 +759,6 @@ indicare l'indirizzo di \textit{loopback}, che a sua volta viene inizializzata
 staticamente a \const{IN6ADRR\_LOOPBACK\_INIT}.
 
 
-
 \subsection{La funzione \func{connect}}
 \label{sec:TCP_func_connect}
 
@@ -822,15 +821,18 @@ sopra), quelle che per
 o problemi nella chiamata della funzione sono le seguenti:
 \begin{enumerate}
 \item Il client non riceve risposta al SYN: l'errore restituito è
-  \errcode{ETIMEDOUT}. Stevens riporta che BSD invia un primo SYN alla chiamata
-  di \func{connect}, un altro dopo 6 secondi, un terzo dopo 24 secondi, se
-  dopo 75 secondi non ha ricevuto risposta viene ritornato l'errore. Linux
-  invece ripete l'emissione del SYN ad intervalli di 30 secondi per un numero
-  di volte che può essere stabilito dall'utente sia con una opportuna
-  \func{sysctl} che attraverso il filesystem \file{/proc} scrivendo il valore
-  voluto in \file{/proc/sys/net/ipv4/tcp\_syn\_retries}. Il valore predefinito
-  per la ripetizione dell'invio è di 5 volte, che comporta un timeout dopo
-  circa 180 secondi.
+  \errcode{ETIMEDOUT}. Stevens riporta che BSD invia un primo SYN alla
+  chiamata di \func{connect}, un altro dopo 6 secondi, un terzo dopo 24
+  secondi, se dopo 75 secondi non ha ricevuto risposta viene ritornato
+  l'errore. Linux invece ripete l'emissione del SYN ad intervalli di 30
+  secondi per un numero di volte che può essere stabilito dall'utente. Questo
+  può essere fatto a livello globale con una opportuna
+  \func{sysctl},\footnote{o più semplicemente scrivendo il valore voluto in
+    \file{/proc/sys/net/ipv4/tcp\_syn\_retries}, vedi
+    sez.~\ref{sec:sock_ipv4_sysctl}.} e a livello di singolo socket con
+  l'opzione \const{TCP\_SYNCNT} (vedi sez.~\ref{sec:sock_tcp_udp_options}). Il
+  valore predefinito per la ripetizione dell'invio è di 5 volte, che comporta
+  un timeout dopo circa 180 secondi.
 
 \item Il client riceve come risposta al SYN un RST significa che non c'è
   nessun programma in ascolto per la connessione sulla porta specificata (il
@@ -910,11 +912,11 @@ con cui il kernel tratta le connessioni in arrivo. Per ogni socket in ascolto
 infatti vengono mantenute due code:
 \begin{enumerate}
 \item La coda delle connessioni incomplete (\textit{incomplete connection
-    queue} che contiene un riferimento per ciascun socket per il quale è
-  arrivato un SYN ma il \itindex{three~way~handshake}\textit{three way
+    queue}) che contiene un riferimento per ciascun socket per il quale è
+  arrivato un SYN ma il \itindex{three~way~handshake} \textit{three way
     handshake} non si è ancora concluso.  Questi socket sono tutti nello stato
   \texttt{SYN\_RECV}.
-\item La coda delle connessioni complete (\textit{complete connection queue}
+\item La coda delle connessioni complete (\textit{complete connection queue})
   che contiene un ingresso per ciascun socket per il quale il
   \itindex{three~way~handshake} \textit{three way handshake} è stato
   completato ma ancora \func{accept} non è ritornata.  Questi socket sono
@@ -2387,13 +2389,13 @@ si aveva il SYN flag attivo.  Si noti come a partire dal secondo pacchetto sia
 sempre attivo il campo \texttt{ack}, seguito dal numero di sequenza per il
 quale si da il ricevuto; quest'ultimo, a partire dal terzo pacchetto, viene
 espresso in forma relativa per maggiore compattezza.  Il campo \texttt{win} in
-ogni riga indica la \textit{advertising window} di cui parlavamo in
-sez.~\ref{sec:TCP_TCP_opt}.  Allora si può verificare dall'output del comando
-come venga appunto realizzata la sequenza di pacchetti descritta in
-sez.~\ref{sec:TCP_conn_cre}: prima viene inviato dal client un primo pacchetto
-con il SYN che inizia la connessione, a cui il server risponde dando il
-ricevuto con un secondo pacchetto, che a sua volta porta un SYN, cui il client
-risponde con un il terzo pacchetto di ricevuto.
+ogni riga indica la \itindex{advertised~window} \textit{advertised window} di
+cui parlavamo in sez.~\ref{sec:TCP_TCP_opt}.  Allora si può verificare
+dall'output del comando come venga appunto realizzata la sequenza di pacchetti
+descritta in sez.~\ref{sec:TCP_conn_cre}: prima viene inviato dal client un
+primo pacchetto con il SYN che inizia la connessione, a cui il server risponde
+dando il ricevuto con un secondo pacchetto, che a sua volta porta un SYN, cui
+il client risponde con un il terzo pacchetto di ricevuto.
 
 Ritorniamo allora alla nostra sessione con il servizio echo: dopo le tre righe
 del \textit{three way handshake} \itindex{three~way~handshake} non avremo nulla
@@ -2607,9 +2609,9 @@ Il risultato finale qui dipende dall'implementazione dello stack TCP, e nel
 caso di Linux anche dall'impostazione di alcuni dei parametri di sistema che
 si trovano in \file{/proc/sys/net/ipv4}, che ne controllano il comportamento:
 in questo caso in particolare da \file{tcp\_retries2} (vedi
-sez.~\ref{sec:sock_sysctl}). Questo parametro infatti specifica il numero di
-volte che deve essere ritentata la ritrasmissione di un pacchetto nel mezzo di
-una connessione prima di riportare un errore di timeout.  Il valore
+sez.~\ref{sec:sock_ipv4_sysctl}). Questo parametro infatti specifica il numero
+di volte che deve essere ritentata la ritrasmissione di un pacchetto nel mezzo
+di una connessione prima di riportare un errore di timeout.  Il valore
 preimpostato è pari a 15, il che comporterebbe 15 tentativi di ritrasmissione,
 ma nel nostro caso le cose sono andate diversamente, dato che le
 ritrasmissioni registrate da \cmd{tcpdump} sono solo 8; inoltre l'errore
@@ -3393,17 +3395,18 @@ successiva \func{select} ritorner
 disponibilità.
 
 Il nostro server comunque soffre di una vulnerabilità per un attacco di tipo
-\textit{Denial of Service}. Il problema è che in caso di blocco di una
-qualunque delle funzioni di I/O, non avendo usato processi separati, tutto il
-server si ferma e non risponde più a nessuna richiesta. Abbiamo scongiurato
-questa evenienza per l'I/O in ingresso con l'uso di \func{select}, ma non vale
-altrettanto per l'I/O in uscita. Il problema pertanto può sorgere qualora una
-delle chiamate a \func{write} effettuate da \func{FullWrite} si blocchi. Con
-il funzionamento normale questo non accade in quanto il server si limita a
-scrivere quanto riceve in ingresso, ma qualora venga utilizzato un client
-malevolo che esegua solo scritture e non legga mai indietro l'\textsl{eco} del
-server, si potrebbe giungere alla saturazione del buffer di scrittura, ed al
-conseguente blocco del server su di una \func{write}.
+\itindex{Denial~of~Service~(DoS)} \textit{Denial of Service}. Il problema è
+che in caso di blocco di una qualunque delle funzioni di I/O, non avendo usato
+processi separati, tutto il server si ferma e non risponde più a nessuna
+richiesta. Abbiamo scongiurato questa evenienza per l'I/O in ingresso con
+l'uso di \func{select}, ma non vale altrettanto per l'I/O in uscita. Il
+problema pertanto può sorgere qualora una delle chiamate a \func{write}
+effettuate da \func{FullWrite} si blocchi. Con il funzionamento normale questo
+non accade in quanto il server si limita a scrivere quanto riceve in ingresso,
+ma qualora venga utilizzato un client malevolo che esegua solo scritture e non
+legga mai indietro l'\textsl{eco} del server, si potrebbe giungere alla
+saturazione del buffer di scrittura, ed al conseguente blocco del server su di
+una \func{write}.
 
 Le possibili soluzioni in questo caso sono quelle di ritornare ad eseguire il
 ciclo di risposta alle richieste all'interno di processi separati, utilizzare
index 2bb10eb472829fe991adeb53e3bea6e9994de38e..6ad3241b00d545fc684f6842ed8a4389520133ae 100644 (file)
@@ -52,9 +52,13 @@ fig.~\ref{fig:TCP_state_diag} sono gli stessi che vengono riportati del
 comando \cmd{netstat} nel campo \textit{State}.
 
 
+\itindbeg{Maximum~Segment~Size|(}
 % TODO trattare la MSS
-% TODO trattare la advertised window
+\itindend{Maximum~Segment~Size|)}
 
+\itindbeg{advertised~window|(}
+% TODO trattare la advertised window
+\itindend{advertised~window|)}