Grandi pulizie di primavera... dimmi te se uno deve sprecare le ferie cosi`
[gapil.git] / elemtcp.tex
index 37745f2ac447edfed010194d17c4f748abc3c718..7929fcca6c6e400e0606c5e75a0f1cfc0f7728db 100644 (file)
@@ -4,7 +4,7 @@
 In questo capitolo inizieremo ad approndire la conoscenza dei socket TCP,
 tratteremo qui dunque il funzionamento delle varie funzioni che si sono usate
 nei due esempi elementari forniti in precedenza (vedi \ref{sec:net_cli_sample}
 In questo capitolo inizieremo ad approndire la conoscenza dei socket TCP,
 tratteremo qui dunque il funzionamento delle varie funzioni che si sono usate
 nei due esempi elementari forniti in precedenza (vedi \ref{sec:net_cli_sample}
-e \ref{sec:net_cli_server}), previa una descrizione delle principali
+e \ref{sec:net_serv_sample}), previa una descrizione delle principali
 caratteristiche del funzionamento di una connessione TCP.
 
 La seconda parte del capitolo sarà poi dedicata ad una riscrittura
 caratteristiche del funzionamento di una connessione TCP.
 
 La seconda parte del capitolo sarà poi dedicata ad una riscrittura
@@ -20,28 +20,219 @@ Prima di entrare nei dettagli di come si usano le varie funzioni dei socket
 che operano con TCP, è fondamentale capire alcune basi del funzionamento del
 protocollo, ed in particolare su come si stabilisce una connessione, come la
 si conclude e qual'è il significato dei vari stati del protocollo ad essa
 che operano con TCP, è fondamentale capire alcune basi del funzionamento del
 protocollo, ed in particolare su come si stabilisce una connessione, come la
 si conclude e qual'è il significato dei vari stati del protocollo ad essa
-connessi; in particolare questo ci permetterà di capire ed usare con profitto
-il programma \texttt{netstat}, che è in grado di mostrare lo stato in cui si
-trova ciascuna connessione attiva.
+connessi.
 
 
-\subsection{Creazione: il \textit{three way handshake}}
+La conoscenza del funzionamento del protocollo è infatti essenziale per capire
+il modello di programmazione ed il funzionamento delle API. In tutto questo è
+di grande aiuto il programma \texttt{netstat}, che useremo per mostrare lo
+stato in cui si trova ciascuna connessione attiva.
+
+\subsection{La creazione della connessione: il \textit{three way handushake}}
 \label{sec:TCPel_conn_cre}
 
 \label{sec:TCPel_conn_cre}
 
+Lo scenario tipico che si verifica quando si deve stabilire una connessione
+TCP (lo stesso usato negli esempi elementari \ref{fig:net_cli_code} e
+\ref{fig:net_serv_code}) la successione degli eventi è la
+seguente:
+
+\begin{itemize}
+\item Il server deve essere preparato per accettare le connessioni in arrivo;
+  il procedimento si chiama \textsl{apertura passiva} del socket (da
+  \textit{passive open}); questo viene fatto chiamando la sequenza di funzioni
+  \texttt{socket}, \texttt{bind} e \texttt{listen}. Infine il server chiama la
+  funzione \texttt{accept} e il processo si blocca in attesa di connessioni.
+  
+\item Il client richiede l'inizio della connessione usando la funzione
+  \texttt{connect}, attraverso un procedimento che viene chiamato
+  \textsl{apertura attiva}, dall'inglese \textit{active open}. La chiamata di
+  \texttt{connect} blocca il processo e causa l'invio da parte del client di
+  un segmento \texttt{SYN}\footnote{Si ricordi che il segmento è l'unità
+    elementare di dati trasmessa dal protocollo TCP al livello superiore;
+    tutti i segmenti hanno un header che contiene le informazioni che servono
+    allo \textit{stack TCP} (così viene di solito chiamata la parte del kernel
+    che implementa il protocollo) per realizzare la comunicazione, fra questi
+    dati ci sono una serie di flag usati per gestire la connessione, come
+    \texttt{SYN}, \texttt{ACK}, \texttt{URG}, \texttt{FIN}, alcuni di essi,
+    come \texttt{SYN} (che sta per \textit{sincronize}) corrispondono a
+    funzioni particolari del protocollo e danno il nome al segmento, (per
+    maggiori dettagli vedere \ref{cha:tcp_protocol})}, in sostanza viene
+  inviato al server un pacchetto IP che contiene solo gli header IP e TCP (con
+  un numero di sequenza) e le opzioni di TCP.
+  
+\item il server deve dare ricevuto (l'\textit{acknowledge}) del \texttt{SYN}
+  del client, inoltre anche il server deve inviare il suo \texttt{SYN} al
+  client (e trasmettere il numero di sequenza iniziale) questo viene fatto
+  ritrasmettendo un singolo segmento in cui entrambi i flag \texttt{SYN}
+  \texttt{ACK} e sono settati.
+  
+\item una volta che il client ha ricevuto l'acknowledge dal server la funzione
+  \texttt{connect} ritorna, l'ultimo passo è dare dare il ricevuto del
+  \texttt{SYN} del server inviando un \texttt{ACK}. Alla ricezione di
+  quest'ultimo la funzione \texttt{accept} del server ritorna e la connessione
+  è stabilita.
+\end{itemize} 
+
+Dato che per compiere tutto questo procedimento devono essere scambiati tre
+pacchetti esso viene generalmente chiamato \textit{three way handshake}. In
+\nfig\ si è rappresentato graficamente lo sequenza di scambio dei segmenti che
+stabilisce la connessione.
+
+% Una analogia citata da R. Stevens per la connessione TCP è quella con il
+% sistema del telefono. La funzione \texttt{socket} può essere considerata
+% l'equivalente di avere un telefono. La funzione \texttt{bind} è analoga al
+% dire alle altre persone qual'è il proprio numero di telefono perché possano
+% chiamare. La funzione \texttt{listen} è accendere il campanello del telefono
+% per sentire le chiamate in arrivo.  La funzione \texttt{connect} richiede di
+% conoscere il numero di chi si vuole chiamare. La funzione \texttt{accept} è
+% quando si risponde al telefono.
 
 
+\begin{figure}[htb]
+  \centering
+  
+  \caption{Il \textit{three way handshake} del TCP}
+  \label{fig:TCPel_TWH}
+\end{figure}
 
 
-\subsection{Il significato delle opzioni del TCP}
+Si noti che figura si sono riportati anche i \textsl{numeri di sequenza}
+associati ai vari pacchetti; per gestire una connessione affidabile infatti il
+protocollo TCP prevede nell'header la presenza di un \textit{sequence number}
+a 32 bit che identifica a quale byte nella sequenza dello stream corrisponde
+il primo byte dei dati contenuti nel segmento.
+
+Il numero di sequenza di ciascun segmento viene calcolato a partire da un
+numero di sequenza iniziale generato in maniera casuale del kernel all'inizio
+della connessione e trasmesso con il SYN; l'acknowledgement di ciascun
+segmento viene effettuato dall'altro capo della connessione settando il flag
+\texttt{ACK} e restituendo nell'apposito campo dell'header un
+\textit{acknowledge number}) pari al numero di sequenza che il ricevente si
+aspetta di ricevere con il pacchetto successivo; dato che il primo pacchetto
+SYN consuma un byte, nel \textit{three way handshake} il numero di acknowledge
+è sempre pari al numero di sequenza iniziale incrementato di uno; lo stesso
+varrà anche (vedi \nfig) per l'acknowledgement di un FIN.
+
+\subsection{Le opzioni TCP.}
 \label{sec:TCPel_TCP_opt}
 
 \label{sec:TCPel_TCP_opt}
 
+Ciascun SYN può contenere delle opzioni per il TCP (le cosiddette \textit{TCP
+  options}, che vengono inserite fra l'header e i dati) che servono a regolare
+la connessione. Normalmente vengono usate le seguenti opzioni:
+
+\begin{itemize}
+\item \textit{MSS option} Sta per \textit{maximum segment size}, con questa
+  opzione ciascun capo della connessione annuncia all'altro il massimo
+  ammontare di dati che vorrebbe accettare per ciascun segmento nella
+  connesione corrente. È possibile leggere e scrivere questo valore attraverso
+  l'opzione del socket \texttt{TCP\_MAXSEG}.
+  
+\item \textit{window scale option} come spiegato in \ref{cha: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'haeader, che così può
+  indicare un massimo di 65535 bytes; ma alcuni tipi di connessione come
+  quelle ad alta velocità (sopra i 45Mbits/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 shiftare a sinistra il valore
+  della finestra annunciata).
+
+\item \textit{timestamp option} è anche questa una nuova opzione necessaria
+  per le connessioni ad alta velocità per evitare possibili corruzioni di dati
+  dovute a pacchetti perduti che riappaiono; anche questa viene negoziata come
+  la precedente.
+
+\end{itemize}
+
+La MSS è generalmente supportata da quasi tutte le implementazioni del
+protocollo, le ultime due opzioni (trattate nell'RFC 1323) sono meno comuni;
+vengono anche dette \textit{long fat pipe options} dato che questo è il nome
+che viene dato alle connessioni caratterizzate da alta velocità o da ritardi
+elevati.
+
+
 \subsection{La terminazione della connessione}
 \label{sec:TCPel_conn_term}
 
 \subsection{La terminazione della connessione}
 \label{sec:TCPel_conn_term}
 
-\subsection{Il diagramma delle transizioni di stato}
-\label{sec:TCPel_trans_dia}
+Mentre per creare una connessione occorre un interscambio di tre segmenti, la
+procedura di chiusura ne richede ben quattro; in questo caso la successione
+degli eventi è la seguente:
+
+\begin{enumerate}
+\item Un processo ad uno dei due capi chiama la funzione \texttt{close}, dando
+  l'avvio a quella che viene chiamata \textsl{chiusura attiva} (da
+  \textit{active close}). Questo comporta l'emissione di un segmento FIN, che
+  significa che si è finito con l'invio dei dati sulla connessione.
+  
+\item L'altro capo della connessione riceve il FIN ed esegue la
+  \textit{chiusura passiva} (da \textit{passive close}); al FIN, come per
+  tutti i pacchetti, viene risposto con un ACK. Inoltre il ricevimento del FIN
+  viene passato al processo che ha aperto il socket come un end of file sulla
+  lettura (dopo che ogni altro eventuale dato rimasto in coda è stato
+  ricevuto), dato che il ricevimento di un FIN significa che non si
+  riceveranno altri dati sulla connessione.
+
+\item Dopo un certo tempo anche il secondo processo chiamerà la funzione
+  \texttt{close} sul proprio socket, causando l'emissione di un altro segmento
+  FIN. 
+  
+\item L'altro capo della connessione riceverà il FIN conclusivo e risponderà
+  con un ACK.
+\end{enumerate}
+
+
+Dato che in questo caso sono richiesti un FIN ed un ACK per ciascuna direzione
+normalmente i segmenti scambiati sono quattro; normalmente giacché in alcune
+sitazioni il FIN del passo 1) è inviato insieme a dei dati. Comunque non è
+detto, anche se è possibile, che i segmenti inviati nei passi 2 e 3, siano
+accorpati in un singolo segmento. In \nfig\ si è rappresentato graficamente lo
+sequenza di scambio dei segmenti che stabilisce la connessione.
+
+\begin{figure}[htb]
+  \centering
+  
+  \caption{Il \textit{three way handshake} del TCP}
+  \label{fig:TCPel_TWH}
+\end{figure}
+
+Come per il SYN anche il FIN occupa un byte nel numero di sequenza, per cui
+l'ACK riporterà un \textit{acknowledge number} incrementato di uno. 
+
+Si noti che nella sequenza di chiusura fra i passi 2 e 3 è in teoria possibile
+che si mantenga un flusso di dati dal capo della connessione che sta eseguendo
+la chiusura passiva a quello che sta eseguendo la chiusura attiva. Nella
+sequenza indicata i dati verrebbero persi, dato che si è chiuso il socket, ma
+esistono situazione in cui si vuole che avvenga proprio questo, che è chiamato
+\texit{half-close}, per cui torneremo su questo aspetto e su come utilizzarlo
+più avanti, quando parleremo della funzione \texttt{shutdown}.
+
+La emissione del FIN avviene quando il socket viene chiuso, questo però non
+avviene solo per la chiamata della funzione \texttt{close}, ma anche alla
+terminazione di un processo, il che vuol dire che se un processo viene
+terminato da un segnale tutte le connessioni aperte verranno chiuse.
+
+
+\subsection{Un esempio di connessione}
+\label{sec:TCPel_conn_dia}
+
+Le operazioni del TCP nella creazione e conclusione di una connessione sono
+specificate attraverso il diagramma di transizione degli stati riportato in
+\nfig. TCP prevede l'esistenza di 11 diversi stati per una connessione ed un
+insieme di regole per le transizioni da uno stato all'altro basate sullo stato
+corrente e sul tipo di segmetno ricevuto.
+
+
 
 \subsection{Lo stato \texttt{TIME\_WAIT}}
 \label{sec:TCPel_time_wait}
 
 
 
 \subsection{Lo stato \texttt{TIME\_WAIT}}
 \label{sec:TCPel_time_wait}
 
 
+
 \section{I numeri di porta}
 \label{sec:TCPel_ports}
 
 \section{I numeri di porta}
 \label{sec:TCPel_ports}
 
@@ -57,9 +248,6 @@ trova ciascuna connessione attiva.
 \subsection{La funzione \texttt{listen}}
 \label{sec:TCPel_func_listen}
 
 \subsection{La funzione \texttt{listen}}
 \label{sec:TCPel_func_listen}
 
-\subsection{La funzione \texttt{connect}}
-\label{sec:TCPel_func_connect}
-
 \subsection{La funzione \texttt{accept}}
 \label{sec:TCPel_func_accept}
 
 \subsection{La funzione \texttt{accept}}
 \label{sec:TCPel_func_accept}