Completata la descrizione dell'esempio dei mutex realizzati con i semafori.
[gapil.git] / elemtcp.tex
index 7929fcca6c6e400e0606c5e75a0f1cfc0f7728db..67157706e24aefc1b3dbaa54fcf4f44caf5918fe 100644 (file)
@@ -1,80 +1,77 @@
 \chapter{Socket TCP elementari}
 \label{cha:elem_TCP_sock}
 
-In questo capitolo inizieremo ad approndire la conoscenza dei socket TCP,
+In questo capitolo iniziamo ad approfondire 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_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
-dell'esempio precedente per trasformarlo in una prima applicazione
-client/server semplice, ma completa, che implementi il servizio standard
-\texttt{time} su TCP (vedremo in seguito un esempio anche con UDP).
+nei due esempi elementari forniti in precedenza (vedi
+\secref{sec:net_cli_sample} e \secref{sec:net_serv_sample}), previa una
+descrizione delle principali caratteristiche del funzionamento di una
+connessione TCP.
 
 
 \section{Il funzionamento di una connessione TCP}
 \label{sec:TCPel_connession}
 
-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
-connessi.
+Prima di entrare nei dettagli delle funzioni usate nelle applicazioni che
+utilizzano i socket TCP, è fondamentale spiegare alcune basi del funzionamento
+del TCP; la conoscenza del funzionamento del protocollo è infatti essenziale
+per capire il modello di programmazione ed il funzionamento delle API.
 
-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.
+In particolare ci concentreremo sulle modalità con le quali il protocollo dà
+inizio e conclude una connessione; faremo inoltre anche un breve accenno al
+significato di alcuni dei vari stati che il protocollo assume durante la vita
+di una connessione, che possono essere osservati per ciascun socket attivo con
+l'uso del programma \cmd{netstat}.
 
-\subsection{La creazione della connessione: il \textit{three way handushake}}
+\subsection{La creazione della connessione: il \textit{three way handshake}}
 \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}
+Il processo che porta a creare una connessione TCP è chiamato \textit{three
+  way handshake}; la successione tipica degli eventi (la stessa che si
+verifica utilizzando il codice dei due precedenti esempi elementari
+\figref{fig:net_cli_code} e \figref{fig:net_serv_code}) che porta alla
+creazione di una connessione è la seguente:
+\begin{enumerate}
 \item Il server deve essere preparato per accettare le connessioni in arrivo;
-  il procedimento si chiama \textsl{apertura passiva} del socket (da
+  il procedimento si chiama \textsl{apertura passiva} del socket (in inglese
   \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.
+  \func{socket}, \func{bind} e \func{listen}. Completata l'apertura passiva il
+  server chiama la funzione \func{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
+  \func{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.
+  \func{connect} blocca il processo e causa l'invio da parte del client di un
+  segmento 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 SYN, ACK,
+    URG, FIN, alcuni di essi, come SYN (che sta per \textit{syncronize})
+    corrispondono a funzioni particolari del protocollo e danno il nome al
+    segmento, (per maggiori dettagli vedere \capref{cha:tcp_protocol}).} in
+  sostanza viene inviato al server un pacchetto IP che contiene solo gli
+  header IP e TCP (con il numero di sequenza iniziale e il flag SYN) 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 il server deve dare ricevuto (l'\textit{acknowledge}) del SYN del
+  client, inoltre anche il server deve inviare il suo SYN al client (e
+  trasmettere il suo numero di sequenza iniziale) questo viene fatto
+  ritrasmettendo un singolo segmento in cui sono impostati entrambi i flag SYN
+  ACK.
   
 \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
+  \func{connect} ritorna, l'ultimo passo è dare dare il ricevuto del SYN del
+  server inviando un ACK. Alla ricezione di quest'ultimo la funzione
+  \func{accept} del server ritorna e la connessione è stabilita.
+\end{enumerate} 
+
+Il procedimento viene chiamato \textit{three way handshake} dato che per
+realizzarlo devono essere scambiati tre segmenti.  In \figref{fig:TCPel_TWH}
+si è rappresentata graficamente la sequenza di scambio dei segmenti che
 stabilisce la connessione.
 
 % Una analogia citata da R. Stevens per la connessione TCP è quella con il
@@ -88,61 +85,65 @@ stabilisce la connessione.
 
 \begin{figure}[htb]
   \centering
-  
+  \includegraphics[width=10cm]{img/three_way_handshake}  
   \caption{Il \textit{three way handshake} del TCP}
   \label{fig:TCPel_TWH}
 \end{figure}
 
-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.
+Si è accennato in precedenza ai \textsl{numeri di sequenza} (che sono anche
+riportati in \figref{fig:TCPel_TWH}); per gestire una connessione affidabile
+infatti il protocollo TCP prevede nell'header la presenza di un numero a 32
+bit (chiamato appunto \textit{sequence number}) che identifica a quale byte
+nella sequenza del flusso corrisponde il primo byte della sezione dati
+contenuta 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
+\textsl{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 impostando
+il flag 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.
+varrà anche (vedi \figref{fig:TCPel_close}) per l'acknowledgement di un FIN.
 
 \subsection{Le opzioni TCP.}
 \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:
+Ciascun segmento SYN contiene in genere delle opzioni per il protocollo TCP
+(le cosiddette \textit{TCP options}, che vengono inserite fra l'header e i
+dati) che servono a comunicare all'altro capo una serie di parametri utili 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
+\item \textit{MSS option}, dove MMS 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}.
+  connessione corrente. È possibile leggere e scrivere questo valore
+  attraverso l'opzione del socket \macro{TCP\_MAXSEG}.
   
-\item \textit{window scale option} come spiegato in \ref{cha:tcp_protocol} il
-  protocollo TCP implementa il controllo di flusso attraverso una
+\item \textit{window scale option}; come spiegato in \capref{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
+  memoria per i dati. Questo è un numero a 16 bit dell'header, che così può
+  indicare un massimo di 65535 byte (anche se Linux usa come massimo 32767 per
+  evitare problemi con alcuni stack bacati che usano l'aritmetica con segno
+  per implementare lo stack TCP); 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 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
   dovute a pacchetti perduti che riappaiono; anche questa viene negoziata come
   la precedente.
@@ -150,71 +151,82 @@ la connessione. Normalmente vengono usate le seguenti opzioni:
 \end{itemize}
 
 La MSS è generalmente supportata da quasi tutte le implementazioni del
-protocollo, le ultime due opzioni (trattate nell'RFC 1323) sono meno comuni;
+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.
-
+elevati. In ogni caso Linux supporta pienamente entrambe le opzioni.
 
 \subsection{La terminazione della connessione}
 \label{sec:TCPel_conn_term}
 
 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:
+procedura di chiusura ne richiede quattro; ancora una volta si può fare
+riferimento al codice degli esempi \figref{fig:net_cli_code} e
+\figref{fig:net_serv_code}, 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
+\item Un processo ad uno dei due capi chiama la funzione \func{close}, dando
+  l'avvio a quella che viene chiamata \textsl{chiusura attiva} (o
   \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
+  \textit{chiusura passiva} (o \textit{passive close}); al FIN, come ad ogni
+  altro pacchetto, viene risposto con un ACK. Inoltre il ricevimento del FIN
+  viene segnalato al processo che ha aperto il socket (dopo che ogni altro
+  eventuale dato rimasto in coda è stato ricevuto) come un end-of-file sulla
+  lettura, questo perché 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
+  \func{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.
+normalmente i segmenti scambiati sono quattro.  Questo non è vero sempre
+giacché in alcune situazioni il FIN del passo 1) è inviato insieme a dei dati.
+Inoltre è possibile che i segmenti inviati nei passi 2 e 3 dal capo che
+effettua la chiusura passiva, siano accorpati in un singolo segmento. In
+\figref{fig:TCPel_close} 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}
+  \centering  
+  \includegraphics[width=10cm]{img/tcp_close}  
+  \caption{La chiusura di una connessione TCP}
+  \label{fig:TCPel_close}
 \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}.
+che si mantenga un flusso di dati dal capo della connessione che deve ancora
+eseguire la chiusura passiva a quello che sta eseguendo la chiusura attiva.
+Nella sequenza indicata i dati verrebbero persi, dato che si è chiuso il
+socket dal lato che esegue la chiusura attiva; esistono tuttavia situazioni in
+cui si vuole poter sfruttare questa possibilità, usando una procedura che è
+chiamata \textit{half-close}; torneremo su questo aspetto e su come
+utilizzarlo più avanti, quando parleremo della funzione \func{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.
+avviene solo per la chiamata della funzione \func{close} (come in
+\figref{fig:net_serv_code}), ma anche alla terminazione di un processo (come
+in \figref{fig:net_cli_code}). Questo vuol dire ad esempio che se un processo
+viene terminato da un segnale tutte le connessioni aperte verranno chiuse.
+
+Infine è da sottolineare che, benché nella figura (e nell'esempio che vedremo
+più avanti in \secref{sec:TCPsimp_echo}) sia stato il client ad eseguire la
+chiusura attiva, nella realtà questa può essere eseguita da uno qualunque dei
+due capi della comunicazione (come in fatto in precedenza nell'esempio di
+\figref{fig:net_serv_code}), e anche se il caso più comune resta quello del
+client, ci sono alcuni servizi, il principale dei quali è l'HTTP, per i
+quali è il server ad effettuare la chiusura attiva.
 
 
 \subsection{Un esempio di connessione}
@@ -222,37 +234,1046 @@ terminato da un segnale tutte le connessioni aperte verranno chiuse.
 
 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.
+\figref{fig:TPCel_conn_example}. TCP prevede l'esistenza di 11 diversi stati
+per un socket ed un insieme di regole per le transizioni da uno stato
+all'altro basate sullo stato corrente e sul tipo di segmento ricevuto; i nomi
+degli stati sono gli stessi che vengono riportati del comando \cmd{netstat}
+nel campo \textit{State}.
+
+Una descrizione completa del funzionamento del protocollo va al di là degli
+obiettivi di questo libro; un approfondimento sugli aspetti principali si
+trova in \capref{cha:tcp_protocol}, ma per una trattazione esauriente il
+miglior riferimento resta (FIXME citare lo Stevens); qui ci limiteremo a
+descrivere brevemente un semplice esempio di connessione e le transizioni che
+avvengono nei due casi appena citati (creazione e terminazione della
+connessione).
+
+In assenza di connessione lo stato del TCP è \texttt{CLOSED}; quando una
+applicazione esegue una apertura attiva il TCP emette un SYN e lo stato
+diventa \texttt{SYN\_SENT}; quando il TCP riceve la risposta del SYN$+$ACK
+emette un ACK e passa allo stato \texttt{ESTABLISHED}; questo è lo stato
+finale in cui avviene la gran parte del trasferimento dei dati.
 
+Dal lato server in genere invece il passaggio che si opera con l'apertura
+passiva è quello di portare il socket dallo stato \texttt{CLOSED} allo
+stato \texttt{LISTEN} in cui vengono accettate le connessioni.
 
+Dallo stato \texttt{ESTABLISHED} si può uscire in due modi; se un'applicazione
+chiama la \texttt{close} prima di aver ricevuto un end of file (chiusura
+attiva) la transizione è verso lo stato \texttt{FIN\_WAIT\_1}; se invece
+l'applicazione riceve un FIN nello stato \texttt{ESTABLISHED} (chiusura
+passiva) la transizione è verso lo stato \texttt{CLOSE\_WAIT}.
+
+In \figref{fig:TPCel_conn_example} è riportato lo schema dello scambio dei
+pacchetti che avviene per una un esempio di connessione, insieme ai vari stati
+che il protocollo viene ad assumere per i due lati, server e client.
+
+\begin{figure}[htb]
+  \centering
+  \includegraphics[width=9cm]{img/tcp_connection}  
+  \caption{Schema dello scambio di pacchetti per un esempio di connessione}
+  \label{fig:TPCel_conn_example}
+\end{figure}
+
+La connessione viene iniziata dal client che annuncia un MSS di 1460 (un
+valore tipico per IPv4 su Ethernet) con Linux, il server risponde con lo
+stesso valore (ma potrebbe essere anche un valore diverso).
+
+Una volta che la connessione è stabilita il client scrive al server una
+richiesta (che assumiamo stare in un singolo segmento, cioè essere minore dei
+1460 byte annunciati dal server), quest'ultimo riceve la richiesta e
+restituisce una risposta (che di nuovo supponiamo stare in un singolo
+segmento). Si noti che l'acknowledge della richiesta è mandato insieme alla
+risposta, questo viene chiamato \textit{piggybacking} ed avviene tutte le
+volte che che il server è sufficientemente veloce a costruire la risposta, in
+caso contrario si avrebbe prima l'emissione di un ACK e poi l'invio della
+risposta.
+
+Infine si ha lo scambio dei quattro segmenti che terminano la connessione
+secondo quanto visto in \secref{sec:TCPel_conn_term}; si noti che il capo
+della connessione che esegue la chiusura attiva entra nello stato
+\texttt{TIME\_WAIT} su cui torneremo fra poco.
+
+È da notare come per effettuare uno scambio di due pacchetti (uno di richiesta
+e uno di risposta) il TCP necessiti di ulteriori otto segmenti, se invece si
+fosse usato UDP sarebbero stati sufficienti due soli pacchetti. Questo è il
+costo che occorre pagare per avere l'affidabilità garantita dal TCP, se si
+fosse usato UDP si sarebbe dovuto trasferire la gestione di tutta una serie di
+dettagli (come la verifica della ricezione dei pacchetti) dal livello del
+trasporto all'interno dell'applicazione.
+
+Quello che è bene sempre tenere presente è allora quali sono le esigenze che
+si hanno in una applicazione di rete, perché non è detto che TCP sia la
+miglior scelta in tutti i casi (ad esempio se si devono solo scambiare dati
+già organizzati in piccoli pacchetti l'overhead aggiunto può essere eccessivo)
+per questo esistono applicazioni che usano UDP e lo fanno perché nel caso
+specifico le sue caratteristiche di velocità e compattezza nello scambio dei
+dati rispondono meglio alle esigenze che devono essere affrontate.
 
 \subsection{Lo stato \texttt{TIME\_WAIT}}
 \label{sec:TCPel_time_wait}
 
+Come riportato da Stevens in \cite{UNP1} lo stato \texttt{TIME\_WAIT} è
+probabilmente uno degli aspetti meno compresi del protocollo TCP, è infatti
+comune trovare nei newsgroup domande su come sia possibile evitare che
+un'applicazione resti in questo stato lasciando attiva una connessione ormai
+conclusa; la risposta è che non deve essere fatto, ed il motivo cercheremo di
+spiegarlo adesso.
+
+Come si è visto nell'esempio precedente (vedi \figref{fig:TPCel_conn_example})
+\texttt{TIME\_WAIT} è lo stato finale in cui il capo di una connessione che
+esegue la chiusura attiva resta prima di passare alla chiusura definitiva
+della connessione. Il tempo in cui l'applicazione resta in questo stato deve
+essere due volte la MSL (\textit{Maximum Segment Lifetime}).
+
+La MSL è la stima del massimo periodo di tempo che un pacchetto IP può vivere
+sulla rete; questo tempo è limitato perché ogni pacchetto IP può essere
+ritrasmesso dai router un numero massimo di volte (detto \textit{hop limit}).
+Il numero di ritrasmissioni consentito è indicato dal campo TTL dell'header di
+IP (per maggiori dettagli vedi \secref{sec:IP_xxx}), e viene decrementato
+ad ogni passaggio da un router; quando si annulla il pacchetto viene scartato.
+Siccome il numero è ad 8 bit il numero massimo di ``salti'' è di 255, pertanto
+anche se il TTL (da \textit{time to live}) non è propriamente un limite sul
+tempo di vita, si stima che un pacchetto IP non possa restare nella rete per
+più di MSL secondi.
+
+Ogni implementazione del TCP deve scegliere un valore per la MSL (l'RFC~1122
+raccomanda 2 minuti, Linux usa 30 secondi), questo comporta una durata dello
+stato \texttt{TIME\_WAIT} che a seconda delle implementazioni può variare fra
+1 a 4 minuti.
+
+Lo stato \texttt{TIME\_WAIT} viene utilizzato dal protocollo per due motivi
+principali:
+\begin{enumerate}
+\item implementare in maniera affidabile la terminazione della connessione
+  in entrambe le direzioni.
+\item consentire l'eliminazione dei segmenti duplicati dalla rete. 
+\end{enumerate}
+
+Il punto è che entrambe le ragioni sono importanti, anche se spesso si fa
+riferimento solo alla prima; ma è solo se si tiene conto della seconda che si
+capisce il perché della scelta di un tempo pari al doppio della MSL come
+durata di questo stato.
+
+Il primo dei due motivi precedenti si può capire tornando a
+\figref{fig:TPCel_conn_example}: assumendo che l'ultimo ACK della sequenza
+(quello del capo che ha eseguito la chiusura attiva) vanga perso, chi esegue
+la chiusura passiva non ricevendo risposta rimanderà un ulteriore FIN, per
+questo motivo chi esegue la chiusura attiva deve mantenere lo stato della
+connessione per essere in grado di reinviare l'ACK e chiuderla correttamente.
+Se non fosse così la risposta sarebbe un RST (un altro tipo si segmento) che
+verrebbe interpretato come un errore.
+
+Se il TCP deve poter chiudere in maniera pulita entrambe le direzioni della
+connessione allora deve essere in grado di affrontare la perdita di uno
+qualunque dei quattro segmenti che costituiscono la chiusura. Per questo
+motivo lo stato \texttt{TIME\_WAIT} deve essere mantenuto anche dopo l'invio
+dell'ultimo ACK per poter essere in grado di poterne gestire l'eventuale
+ritrasmissione in caso di perdita.
+
+Il secondo motivo è più complesso da capire, e necessita di spiegare meglio
+gli scenari in cui accade che i pacchetti si possono perdere nella rete o
+restare intrappolati, per poi riemergere.
+
+Il caso più comune in cui questo avviene è quello di anomalie
+nell'instradamento; può accadere cioè che un router smetta di funzionare o che
+una connessione fra due router si interrompa. In questo caso i protocolli di
+instradamento dei pacchetti possono impiegare diverso tempo (anche dell'ordine
+dei minuti) prima di trovare e stabilire un percorso alternativo per i
+pacchetti. Nel frattempo possono accadere casi in cui un router manda i
+pacchetti verso un'altro e quest'ultimo li rispedisce indietro, o li manda ad
+un terzo router che li rispedisce al primo, si creano cioè dei circoli (i
+cosiddetti \textit{routing loop}) in cui restano intrappolati i pacchetti.
+
+Se uno di questi pacchetti intrappolati è un segmento di TCP chi l'ha inviato,
+non ricevendo risposta, provvederà alla ritrasmissione e se nel frattempo sarà
+stata stabilita una strada alternativa il pacchetto ritrasmesso giungerà a
+destinazione. 
+
+Ma se dopo un po' di tempo (che non supera il limite dell'MSL, dato che
+altrimenti verrebbe ecceduto il TTL) l'anomalia viene a cessare il circolo di
+instradamento viene spezzato i pacchetti intrappolati potranno essere inviati
+alla destinazione finale, con la conseguenza di avere dei pacchetti duplicati;
+questo è un caso che il TCP deve essere in grado di gestire.
 
+Allora per capire la seconda ragione per l'esistenza dello stato
+\texttt{TIME\_WAIT} si consideri il caso seguente: si supponga di avere una
+connessione fra l'IP 195.110.112.236 porta 1550 e l'IP 192.84.145.100 porta
+22, che questa venga chiusa e che poco dopo si ristabilisca la stessa
+connessione fra gli stessi IP sulle stesse porte (quella che viene detta,
+essendo gli stessi porte e numeri IP, una nuova \textsl{incarnazione} della
+connessione precedente); in questo caso ci si potrebbe trovare con dei
+pacchetti duplicati relativi alla precedente connessione che riappaiono nella
+nuova.
+
+Ma fintanto che il socket non è chiuso una nuova incarnazione non può essere
+creata, per questo un socket TCP resta sempre nello stato \texttt{TIME\_WAIT}
+per un periodo di 2MSL, in modo da attendere MSL secondi per essere sicuri che
+tutti i pacchetti duplicati in arrivo siano stati ricevuti (e scartati) o che
+nel frattempo siano stati eliminati dalla rete, e altri MSL secondi per essere
+sicuri che lo stesso avvenga le risposte nella direzione opposta.
+
+In questo modo il TCP si assicura che quando una viene creata una nuova
+connessione tutti gli eventuali segmenti residui di una precedente connessione
+che possono causare disturbi sono stati eliminati dalla rete.
+
+
+\subsection{I numeri di porta}
+\label{sec:TCPel_port_num}
+
+In un ambiente multitasking in un dato momento più processi possono dover
+usare sia UDP che TCP, e ci devono poter essere più connessioni in
+contemporanea. Per poter tenere distinte le diverse connessioni entrambi i
+protocolli usano i \textsl{numeri di porta}, che fanno parte, come si può
+vedere in \secref{sec:sock_sa_ipv4} e \secref{sec:sock_sa_ipv6} pure delle
+strutture degli indirizzi del socket.
+
+Quando un client contatta un server deve poter identificare con quale dei vari
+possibili server attivi intende parlare. Sia TCP che UDP definiscono un gruppo
+di \textsl{porte conosciute} (le cosiddette \textit{well-known port}) che
+identificano una serie di servizi noti (ad esempio la porta 22 identifica il
+servizio \texttt{ssh}) effettuati da appositi server che rispondono alle
+connessioni verso tali porte.
+
+D'altra parte un client non ha necessità di usare un numero di porta
+specifico, per cui in genere vengono usate le cosiddette \textsl{porte
+  effimere} (o \textit{ephemeral ports}) cioè porte a cui non è assegnato
+nessun servizio noto e che vengono assegnate automaticamente dal kernel alla
+creazione della connessione. Queste sono dette effimere in quanto vengono
+usate solo per la durata della connessione, e l'unico requisito che deve
+essere soddisfatto è che ognuna di esse sia assegnata in maniera univoca.
+
+La lista delle porte conosciute è definita dall'RFC~1700 che contiene l'elenco
+delle porte assegnate dalla IANA (\textit{Internet Assigned Number Authority})
+ma l'elenco viene costantemente aggiornato e pubblicato all'indirizzo
+\texttt{ftp://ftp.isi.edu/in-notes/iana/assignements/port-numbers}, inoltre il
+file \file{/etc/services} contiene un analogo elenco, con la corrispondenza
+fra i numeri di porta ed il nome simbolico del servizio. I numeri sono divisi
+in tre intervalli:
+
+\begin{enumerate}
+\item \textsl{le porte conosciute}. I numeri da 0 a 1023. Queste sono
+  controllate e assegnate dalla IANA. Se è possibile la stessa porta è
+  assegnata allo stesso servizio sia su UDP che su TCP (ad esempio la porta 22
+  è assegnata a ssh su entrambi i protocolli, anche se viene usata solo dal
+  TCP).
+  
+\item \textsl{le porte registrate}. I numeri da 1024 a 49151. Queste porte non
+  sono controllate dalla IANA, che però registra ed elenca chi usa queste
+  porte come servizio agli utenti. Come per le precedenti si assegna una porta
+  ad un servizio sia per TCP che UDP anche se poi il servizio è implementato
+  solo su TCP. Ad esempio X Window usa le porte TCP e UDP dal 6000 al 6063
+  anche se il protocollo è implementato solo tramite TCP.
+  
+\item \textsl{le porte private} o \textsl{dinamiche}. I numeri da 49152 a
+  65535. La IANA non dice nulla riguardo a queste porte che pertanto
+  sono i candidati naturali ad essere usate come porte effimere.
+\end{enumerate}
+
+In realtà rispetto a quanto indicato nell'RFC~1700 i vari sistemi hanno fatto
+scelte diverse per le porte effimere, in particolare in
+\figref{fig:TCPel_port_alloc} sono riportate quelle di BSD, Solaris e Linux.
+Nel caso di Linux poi la scelta fra i due intervalli possibili viene fatta
+dinamicamente a seconda della memoria a disposizione del kernel per gestire le
+relative tabelle.
+
+\begin{figure}[!htb]
+  \centering
+  \includegraphics[width=10cm]{img/port_alloc}  
+  \caption{Allocazione dei numeri di porta}
+  \label{fig:TCPel_port_alloc}
+\end{figure}
+
+I sistemi unix hanno inoltre il concetto di \textsl{porte riservate} (che
+corrispondono alle porte con numero minore di 1024 e coincidono quindi con le
+porte conosciute). La loro caratteristica è che possono essere assegnate a un
+socket solo da un processo con i privilegi di root, per far si che solo
+l'amministratore possa allocare queste porte per far partire i relativi
+servizi.
+
+Si tenga conto poi che ci sono alcuni client (in particolare \cmd{rsh} e
+\cmd{rlogin}) che richiedono una connessione su una porta riservata anche
+dal lato client come parte dell'autenticazione. Questo viene fatto tramite la
+funzione \func{rresvport} assegnando al socket una porta libera
+nell'intervallo fra 512 e 1023.
+
+Data una connessione TCP si suole chiamare \textit{socket pair} la
+combinazione dei quattro numeri che definiscono i due capi della connessione e
+cioè l'indirizzo IP locale e la porta TCP locale, e l'indirizzo IP remoto e la
+porta TCP remota; questa combinazione, che scriveremo usando una notazione del
+tipo (195.110.112.152:22, 192.84.146.100:20100), identifica univocamente una
+connessione su internet. Questo concetto viene di solito esteso anche a UDP,
+benché in questo caso non abbia senso parlare di connessione. L'utilizzo del
+programma \cmd{netstat} permette di visualizzare queste informazioni nei campi
+\textit{Local Address} e \textit{Foreing Address}.
+
+
+\subsection{Le porte ed il modello client/server}
+\label{sec:TCPel_port_cliserv}
+
+Per capire meglio l'uso delle porte e come vengono utilizzate quando si ha a
+che fare con un'applicazione client/server (come quella che scriveremo in
+\secref{sec:TCPel_cunc_serv}) esamineremo cosa accade con le connessioni nel
+caso di un server TCP che deve gestire connessioni multiple.
+
+Se eseguiamo un \cmd{netstat} su una macchina di prova (che supponiamo avere
+indirizzo 195.110.112.152) potremo avere un risultato del tipo:
+\begin{verbatim}
+Active Internet connections (servers and established)
+Proto Recv-Q Send-Q Local Address           Foreign Address         State      
+tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN
+tcp        0      0 0.0.0.0:25              0.0.0.0:*               LISTEN
+tcp        0      0 127.0.0.1:53            0.0.0.0:*               LISTEN
+\end{verbatim}
+essendo presenti e attivi un server ssh, un server di posta e un DNS per il
+caching locale.
+
+Questo ci mostra ad esempio che il server ssh ha compiuto un'apertura passiva
+mettendosi in ascolto sulla porta 22 riservata a questo servizio e che si è
+posto in ascolto per connessioni provenienti da uno qualunque degli indirizzi
+associati alle interfacce locali; la notazione 0.0.0.0 usata da netstat è
+equivalente all'asterisco utilizzato per il numero di porta ed indica il
+valore generico, e corrisponde al valore \macro{INADDR\_ANY} definito in
+\file{arpa/inet.h}.
+
+Inoltre la porta e l'indirizzo di ogni eventuale connessione esterna non sono
+specificati; in questo caso la \textit{socket pair} associata al socket può
+essere indicata come (*:22, *:*), usando l'asterisco anche per gli indirizzi
+come carattere di \textit{wildchard}. 
+
+In genere avendo le macchine associato un solo IP ci si può chiedere che senso
+abbia l'utilizzo dell'indirizzo generico per l'indirizzo locale, ma esistono
+anche macchine che hanno più di un indirizzo IP (il cosiddetto
+\textit{multihoming}) in questo modo si possono accettare connessioni
+indirizzate verso uno qualunque di essi. Ma come si può vedere nell'esempio
+con il DNS in ascolto sulla porta 53 è anche possibile restringere l'accesso
+solo alle connessioni che provengono da uno specifico indirizzo, cosa che nel
+caso è fatta accettando solo connessioni che arrivino sull'interfaccia di
+loopback.
+
+Una volta che ci si vorrà collegare a questa macchina da un'altra posta
+all'indirizzo 192.84.146.100 si potrà lanciare un client \cmd{ssh} per
+creare una connessione verso la precedente, e il kernel assocerà al suddetto
+una porta effimera che per esempio potrà essere la 21100, la connessione
+allora sarà espressa dalla socket pair (192.84.146.100:21100,
+195.110.112.152.22).
+
+Alla ricezione della richiesta dal client il server creerà un processo figlio
+per gestire la connessione, se a questo punto eseguiamo nuovamente il
+programma netstat otterremo come risultato:
+\begin{verbatim}
+Active Internet connections (servers and established)
+Proto Recv-Q Send-Q Local Address           Foreign Address         State      
+tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN
+tcp        0      0 0.0.0.0:25              0.0.0.0:*               LISTEN
+tcp        0      0 127.0.0.1:53            0.0.0.0:*               LISTEN
+tcp        0      0 195.110.112.152:22      192.84.146.100:21100    ESTABLISHED
+\end{verbatim}
+
+Come si può notare il server è ancora in ascolto sulla porta 22, però adesso
+c'è un nuovo socket (con lo stato \texttt{ESTABLISHED}) che anch'esso utilizza
+la porta 22, ed ha specificato l'indirizzo locale, questo è il socket con cui
+il processo figlio gestisce la connessione mentre il padre resta in ascolto
+sul socket originale.
+
+Se a questo punto lanciamo un'altra volta il client ssh per una seconda
+connessione quello che otterremo usando netstat sarà qualcosa del genere:
+\begin{verbatim}
+Active Internet connections (servers and established)
+Proto Recv-Q Send-Q Local Address           Foreign Address         State      
+tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN
+tcp        0      0 0.0.0.0:25              0.0.0.0:*               LISTEN
+tcp        0      0 127.0.0.1:53            0.0.0.0:*               LISTEN
+tcp        0      0 195.110.112.152:22      192.84.146.100:21100    ESTABLISHED
+tcp        0      0 195.110.112.152:22      192.84.146.100:21101    ESTABLISHED
+\end{verbatim}
+cioè il client effettuerà la connessione usando un'altra porta effimera, con
+questa sarà aperta la connessione, ed il server creerà un'altro processo
+figlio sarà creato per gestirla.
+
+Tutto ciò mostra come TCP, per poter gestire le connessioni con un server
+concorrente, non può suddividere i pacchetti solo sulla base della porta di
+destinazione, ma deve usare tutta l'informazione contenuta nella socket pair,
+compresa la porta dell'indirizzo remoto.  E se andassimo a vedere quali sono i
+processi a cui fanno riferimento i vari socket vedremmo che i pacchetti che
+arrivano dalla porta remota 21100 vanno al primo figlio e quelli che arrivano
+alla porta 21101 al secondo.
 
-\section{I numeri di porta}
-\label{sec:TCPel_ports}
 
 \section{Le funzioni dei socket TCP}
 \label{sec:TCPel_functions}
 
-\subsection{La funzione \texttt{connect}}
-\label{sec:TCPel_func_connect}
+In questa sezione descriveremo in dettaglio le varie funzioni necessarie per
+l'uso dei socket TCP già citate in precedenza (e utilizzate nei due esempi
+\secref{sec:net_cli_sample} e \secref{sec:net_serv_sample}) con l'eccezione
+della funzione \func{socket} che è già stata esaminata in dettaglio in
+\secref{sec:sock_socket}.
+
+In \figref{fig:TCPel_cliserv_func} abbiamo un tipico schema di funzionamento
+di un'applicazione client-server che usa i socket TCP: prima il server viene
+avviato ed in seguito il client si connette, in questo caso, a differenza di
+quanto accadeva con gli esempi elementari del \capref{cha:network} si assume
+che sia il client ad effettuare delle richieste a cui il server risponde, il
+client notifica poi di avere concluso inviando un end-of-file a cui il server
+risponderà anche lui chiudendo la connessione per aspettarne una nuova.
+
+\begin{figure}[!htb]
+  \centering
+
+  \caption{Struttura delle funzioni dei socket per una semplice applicazione
+    client/server su TCP.}
+  \label{fig:TCPel_cliserv_func}
+\end{figure}
+
+Useremo questo schema anche per l'esempio di reimplementazione del servizio
+\texttt{daytime} che illustreremo in \secref{sec:TCPel_cunc_serv}.
+
 
-\subsection{La funzione \texttt{bind}}
+\subsection{La funzione \func{bind}}
 \label{sec:TCPel_func_bind}
 
-\subsection{La funzione \texttt{listen}}
+La funzione \func{bind} assegna un indirizzo locale ad un socket. È usata
+cioè per specificare la prima parte dalla socket pair. Viene usata sul lato
+server per specificare la porta (e gli eventuali indirizzi locali) su cui poi
+ci si porrà in ascolto. Il prototipo della funzione è il seguente:
+\begin{prototype}{sys/socket.h}
+{int bind(int sockfd, const struct sockaddr *serv\_addr, socklen\_t addrlen)}
+  
+  Il primo argomento è un file descriptor ottenuto da una precedente chiamata
+  a \func{socket}, mentre il secondo e terzo argomento sono rispettivamente
+  l'indirizzo (locale) del socket e la dimensione della struttura che lo
+  contiene, secondo quanto già trattato in \secref{sec:sock_sockaddr}.
+  
+  \bodydesc{La funzione restituisce zero in caso di successo e -1 per un
+    errore; in caso di errore la variabile \var{errno} viene impostata secondo
+    i seguenti codici di errore:
+  \begin{errlist}
+  \item[\macro{EBADF}] il file descriptor non è valido.
+  \item[\macro{EINVAL}] il socket ha già un indirizzo assegnato.
+  \item[\macro{ENOTSOCK}] il file descriptor non è associato ad un socket.
+  \item[\macro{EACCESS}] si è cercato di usare una porta riservata senza
+    sufficienti privilegi. 
+  \end{errlist}}
+\end{prototype}
+
+Con il TCP la chiamata \func{bind} permette di specificare l'indirizzo, la
+porta, entrambi o nessuno dei due. In genere i server utilizzano una porta
+nota che assegnano all'avvio, se questo non viene fatto è il kernel a
+scegliere una porta effimera quando vengono eseguite la funzioni
+\func{connect} o \func{listen}, ma se questo è normale per il client non lo è
+per il server\footnote{un'eccezione a tutto ciò sono i server che usano RPC.
+  In questo caso viene fatta assegnare dal kernel una porta effimera che poi
+  viene registrata presso il \textit{portmapper}; quest'ultimo è un altro
+  demone che deve essere contattato dai client per ottenere la porta effimera
+  su cui si trova il server.} che in genere viene identificato dalla porta su
+cui risponde.
+
+Con \func{bind} si può assegnare un IP specifico ad un socket, purché questo
+appartenga ad una interfaccia della macchina.  Per un client TCP questo
+diventerà l'indirizzo sorgente usato per i tutti i pacchetti inviati sul
+socket, mentre per un server TCP questo restringerà l'accesso al socket solo
+alle connessioni che arrivano verso tale indirizzo.
+
+Normalmente un client non specifica mai un indirizzo ad un suo socket, ed il
+kernel sceglie l'indirizzo di origine quando viene effettuata la connessione
+sulla base dell'interfaccia usata per trasmettere i pacchetti, (che dipende
+dalle regole di instradamento usate per raggiungere il server).
+Se un server non specifica il suo indirizzo locale il kernel userà come
+indirizzo di origine l'indirizzo di destinazione specificato dal SYN del
+client. 
+
+Per specificare un indirizzo generico con IPv4 si usa il valore
+\macro{INADDR\_ANY}, il cui valore, come visto anche negli esempi precedenti
+è pari a zero, nell'esempio \figref{fig:net_serv_code} si è usata
+un'assegnazione immediata del tipo:
+
+\footnotesize
+\begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
+    serv_add.sin_addr.s_addr = htonl(INADDR_ANY);   /* connect from anywhere */
+\end{lstlisting}
+\normalsize
+
+Si noti che si è usato \func{htonl} per assegnare il valore
+\macro{INADDR\_ANY}; benché essendo questo pari a zero il riordinamento sia
+inutile; ma dato che tutte le costanti \macro{INADDR\_} sono definite
+secondo l'ordinamento della macchina è buona norma usare sempre la funzione
+\macro{htonl}.
+
+L'esempio precedete funziona con IPv4 dato che l'indirizzo è rappresentabile
+anche con un intero a 32 bit; non si può usare lo stesso metodo con IPv6,
+in cui l'indirizzo è specificato come struttura, perché il linguaggio C non
+consente l'uso di una struttura costante come operando a destra in una
+assegnazione.  
+
+Per questo nell'header \file{netinet/in.h} è definita una variabile
+\type{in6addr\_any} (dichiarata come \ctyp{extern}, ed inizializzata dal
+sistema al valore \macro{IN6ADRR\_ANY\_INIT}) che permette di effettuare una
+assegnazione del tipo: 
+
+\footnotesize
+\begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
+    serv_add.sin6_addr = in6addr_any;   /* connect from anywhere */
+\end{lstlisting}
+\normalsize
+
+
+\subsection{La funzione \func{connect}}
+\label{sec:TCPel_func_connect}
+
+La funzione \func{connect} è usata da un client TCP per stabilire la
+connessione con un server TCP, il prototipo della funzione è il seguente:
+\begin{prototype}{sys/socket.h}
+{int connect(int sockfd, const struct sockaddr *servaddr, socklen\_t addrlen)}
+  
+  Il primo argomento è un file descriptor ottenuto da una precedente chiamata
+  a \func{socket}, mentre il secondo e terzo argomento sono rispettivamente
+  l'indirizzo e la dimensione della struttura che contiene l'indirizzo del
+  socket, già descritta in \secref{sec:sock_sockaddr}.
+  
+  \bodydesc{La funzione restituisce zero in caso di successo e -1 per un
+    errore, in caso di errore la variabile \var{errno} viene impostata secondo
+    i seguenti codici di errore:
+  \begin{errlist}
+  \item[\macro{ECONNREFUSED}] non c'è nessuno in ascolto sull'indirizzo remoto.
+  \item[\macro{ETIMEDOUT}] si è avuto timeout durante il tentativo di
+    connessione.
+  \item[\macro{ENETUNREACH}] la rete non è raggiungibile.
+  \item[\macro{EINPROGRESS}] il socket è non bloccante (vedi
+    \secref{sec:file_noblocking}) e la connessione non può essere conclusa
+    immediatamente.
+  \item[\macro{EALREADY}] il socket è non bloccante (vedi
+    \secref{sec:file_noblocking}) e un tentativo precedente di connessione non
+    si è ancora concluso.
+  \item[\macro{EAGAIN}] non ci sono più porte locali libere. 
+  \item[\macro{EAFNOSUPPORT}] l'indirizzo non ha una famiglia di indirizzi
+    corretta nel relativo campo.
+  \item[\macro{EACCESS, EPERM}] si è tentato di eseguire una connessione ad un
+    indirizzo broadcast senza che il socket fosse stato abilitato per il
+    broadcast.
+  \end{errlist}
+  altri errori possibili sono: \macro{EFAULT}, \macro{EBADF},
+  \macro{ENOTSOCK}, \macro{EISCONN} e \macro{EADDRINUSE}.}
+\end{prototype}
+
+La struttura dell'indirizzo deve essere inizializzata con l'indirizzo IP e il
+numero di porta del server a cui ci si vuole connettere, come mostrato
+nell'esempio \secref{sec:net_cli_sample} usando le funzioni illustrate in
+\secref{sec:sock_addr_func}.
+
+Nel caso di socket TCP la funzione \func{connect} avvia il \textit{three way
+  handshake}, e ritorna solo quando la connessione è stabilita o si è
+verificato un errore. Le possibili cause di errore sono molteplici (ed i
+relativi codici riportati sopra), quelle che però dipendono dalla situazione
+della rete e non da errori o problemi nella chiamata della funzione sono le
+seguenti:
+\begin{enumerate}
+\item Il client non riceve risposta al SYN: l'errore restituito è
+  \macro{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.
+%
+% Le informazioni su tutte le opzioni impostabili via /proc stanno in
+% Linux/Documentation/networking/ip-sysctl.txt
+%
+\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
+  che vuol dire probabilmente che o si è sbagliato il numero della porta o che
+  non è stato avviato il server), questo è un errore fatale e la funzione
+  ritorna non appena il RST viene ricevuto riportando un errore
+  \macro{ECONNREFUSED}.
+  
+  Il flag RST sta per \textit{reset} ed è un segmento inviato direttamente
+  dal TCP quando qualcosa non va. Tre condizioni che generano un RST sono:
+  quando arriva un SYN per una porta che non ha nessun server in ascolto,
+  quando il TCP abortisce una connessione in corso, quando TCP riceve un
+  segmento per una connessione che non esiste.
+  
+\item Il SYN del client provoca l'emissione di un messaggio ICMP di
+  destinazione non raggiungibile. In questo caso dato che il messaggio può
+  essere dovuto ad una condizione transitoria si ripete l'emissione dei SYN
+  come nel caso precedente, fino al timeout, e solo allora si restituisce il
+  codice di errore dovuto al messaggio ICMP, che da luogo ad un
+  \macro{ENETUNREACH}.
+   
+\end{enumerate}
+
+Se si fa riferimento al diagramma degli stati del TCP riportato in
+\figref{fig:TCP_state_diag} la funzione \func{connect} porta un socket
+dallo stato \texttt{CLOSED} (lo stato iniziale in cui si trova un socket
+appena creato) prima allo stato \texttt{SYN\_SENT} e poi, al ricevimento del
+ACK, nello stato \texttt{ESTABLISHED}. Se invece la connessione fallisce il
+socket non è più utilizzabile e deve essere chiuso.
+
+Si noti infine che con la funzione \func{connect} si è specificato solo
+indirizzo e porta del server, quindi solo una metà della socket pair; essendo
+questa funzione usata nei client l'altra metà contenente indirizzo e porta
+locale viene lasciata all'assegnazione automatica del kernel, e non è
+necessario effettuare una \func{bind}.
+
+
+\subsection{La funzione \func{listen}}
 \label{sec:TCPel_func_listen}
 
-\subsection{La funzione \texttt{accept}}
+La funzione \func{listen} è usata per usare un socket in modalità passiva,
+cioè, come dice il nome, per metterlo in ascolto di eventuali connessioni; in
+sostanza l'effetto della funzione è di portare il socket dallo stato
+\texttt{CLOSED} a quello \texttt{LISTEN}. In genere si chiama la funzione in
+un server dopo le chiamate a \func{socket} e \func{bind} e prima della
+chiamata ad \func{accept}. Il prototipo della funzione come definito dalla
+pagina di manuale è:
+\begin{prototype}{sys/socket.h}{int listen(int sockfd, int backlog)}
+  La funzione pone il socket specificato da \var{sockfd} in modalità
+  passiva e predispone una coda per le connessioni in arrivo di lunghezza pari
+  a \var{backlog}. La funzione si può applicare solo a socket di tipo
+  \macro{SOCK\_STREAM} o \macro{SOCK\_SEQPACKET}.
+  
+  \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
+    errore. I codici di errore restituiti in \var{errno} sono i seguenti:
+  \begin{errlist}
+  \item[\macro{EBADF}] l'argomento \var{sockfd} non è un file descriptor
+    valido.
+  \item[\macro{ENOTSOCK}] l'argomento \var{sockfd} non è un socket.
+  \item[\macro{EOPNOTSUPP}] il socket è di un tipo che non supporta questa
+    operazione.
+  \end{errlist}}
+\end{prototype}
+
+
+Il parametro \var{backlog} indica il numero massimo di connessioni pendenti
+accettate; se esso viene ecceduto il client riceverà una errore di tipo
+\macro{ECONNREFUSED}, o se il protocollo, come nel caso del TCP, supporta la
+ritrasmissione, la richiesta sarà ignorata in modo che la connessione possa
+essere ritentata.
+
+Per capire meglio il significato di tutto ciò occorre approfondire la modalità
+con cui il kernel tratta le connessioni in arrivo. Per ogni socket in ascolto
+infatti vengono mantenute due code:
+\begin{enumerate}
+\item Una coda delle connessioni incomplete (\textit{incomplete connection
+    queue} che contiene un ingresso per ciascun socket per il quale è arrivato
+  un SYN ma il three way handshake non si è ancora concluso.  Questi socket
+  sono tutti nello stato \texttt{SYN\_RECV}.
+\item Una coda delle connessioni complete (\textit{complete connection queue}
+  che contiene un ingresso per ciascun socket per il quale il three way
+  handshake è stato completato ma ancora \func{accept} non è ritornata.
+  Questi socket sono tutti nello stato \texttt{ESTABLISHED}.
+\end{enumerate}
+
+Lo schema di funzionamento è descritto in \figref{fig:TCPel_xxx}, quando
+arriva un SYN da un client il server crea una nuova entrata nella coda delle
+connessioni incomplete, e poi risponde con il SYN$+$ACK. La entrata resterà
+nella coda delle connessioni incomplete fino al ricevimento dell'ACK dal
+client o fino ad un timeout. Nel caso di completamento del three way handshake
+l'entrata viene sostata nella coda delle connessioni complete. Quando il
+processo chiama la funzione \func{accept} (vedi
+\secref{sec:TCPel_func_accept}) la prima entrata nella coda delle connessioni
+complete è passata al programma, o, se la coda è vuota, il processo viene
+posto in attesa e risvegliato all'arrivo della prima connessione completa.
+
+Storicamente il valore del parametro \var{backlog} era corrispondente al
+massimo valore della somma del numero di entrate possibili per ciascuna di
+dette code. Stevens riporta che BSD ha sempre applicato un fattore di 1.5 al
+valore, e provvede una tabella con i risultati ottenuti con vari kernel,
+compreso Linux 2.0, che mostrano le differenze fra diverse implementazioni. 
+
+In Linux il significato di questo valore è cambiato a partire dal kernel 2.2
+per prevenire l'attacco chiamato \textit{syn flood}. Questo si basa
+sull'emissione da parte dell'attaccante di un grande numero di pacchetti SYN
+indirizzati verso una porta forgiati con indirizzo IP fasullo\footnote{con la
+  tecnica che viene detta \textit{ip spoofing}.} così che i SYN$+$ACK vanno
+perduti e la coda delle connessioni incomplete viene saturata, impedendo di
+fatto ulteriori connessioni.
+
+Per ovviare a questo il significato del \var{backlog} è stato cambiato a
+indicare la lunghezza della coda delle connessioni complete. La lunghezza
+della coda delle connessioni incomplete può essere ancora controllata usando
+la \func{sysctl} o scrivendola direttamente in
+\file{/proc/sys/net/ipv4/tcp\_max\_syn\_backlog}. Quando si attiva la
+protezione dei syncookies però (con l'opzione da compilare nel kernel e da
+attivare usando \file{/proc/sys/net/ipv4/tcp\_syncookies}) questo valore
+viene ignorato e non esiste più un valore massimo.  In ogni caso in Linux il
+valore di \var{backlog} viene troncato ad un massimo di \macro{SOMAXCONN}
+se è superiore a detta costante (che di default vale 128).
+
+La scelta storica per il valore di questo parametro è di 5, e alcuni vecchi
+kernel non supportavano neanche valori superiori, ma la situazione corrente è
+molto cambiata per via della presenza di server web che devono gestire un gran
+numero di connessioni per cui un tale valore non è più adeguato. Non esiste
+comunque una risposta univoca per la scelta del valore, per questo non
+conviene specificarlo con una costante (il cui cambiamento richiederebbe la
+ricompilazione del server) ma usare piuttosto una variabile di ambiente (vedi
+\secref{sec:proc_environ}).  
+
+Lo Stevens tratta accuratamente questo argomento, con esempi presi da casi
+reali su web server, ed in particolare evidenzia come non sia più vero che il
+compito principale della coda sia quello di gestire il caso in cui il server è
+occupato fra chiamate successive alla \func{accept} (per cui la coda più
+occupata sarebbe quella delle connessioni completate), ma piuttosto quello di
+gestire la presenza di un gran numero di SYN in attesa di concludere il
+three way handshake.
+
+Infine va messo in evidenza che nel caso di socket TCP quando un SYN arriva
+con tutte le code piene, il pacchetto deve essere ignorato. Questo perché la
+condizione in cui le code sono piene è ovviamente transitoria, per cui se il
+client ritrasmette il SYN è probabile che passato un po' di tempo possa
+trovare nella coda lo spazio per una nuova connessione. Se invece si
+rispondesse con un RST per indicare l'impossibilità di effettuare la
+connessione la chiamata a \func{connect} nel client ritornerebbe con una
+condizione di errore, costringendo a inserire nell'applicazione la gestione
+dei tentativi di riconnessione che invece può essere effettuata in maniera
+trasparente dal protocollo TCP.
+
+
+\subsection{La funzione \func{accept}}
 \label{sec:TCPel_func_accept}
 
+La funzione \func{accept} è chiamata da un server TCP per gestire la
+connessione una volta che sia stato completato il three way handshake, la
+funzione restituisce un nuovo socket descriptor su cui si potrà operare per
+effettuare la comunicazione. Se non ci sono connessioni completate il processo
+viene messo in attesa. Il prototipo della funzione è il seguente:
+\begin{prototype}{sys/socket.h}
+{int accept(int sockfd, struct sockaddr *addr, socklen\_t *addrlen)} 
+  Estrae la prima connessione relativa al socket \var{sockfd}
+  in attesa sulla coda delle connessioni complete, che associa ad nuovo socket
+  con le stesse caratteristiche di \var{sockfd} (restituito dalla funzione
+  stessa).  Il socket originale non viene toccato. Nella struttura
+  \var{addr} e nella variabile \var{addrlen} vengono restituiti
+  indirizzo e relativa lunghezza del client che si è connesso.
+  \bodydesc{La funzione restituisce un numero di socket descriptor positivo in
+    caso di successo e -1 in caso di errore, nel qual caso la variabile
+    \var{errno} viene impostata ai seguenti valori:
+
+  \begin{errlist}
+  \item[\macro{EBADF}] l'argomento \var{sockfd} non è un file descriptor
+    valido.
+  \item[\macro{ENOTSOCK}] l'argomento \var{sockfd} non è un socket.
+  \item[\macro{EOPNOTSUPP}] il socket è di un tipo che non supporta questa
+    operazione.    
+  \item[\macro{EAGAIN} o \macro{EWOULDBLOCK}] il socket è stato impostato come
+    non bloccante (vedi \secref{sec:file_noblocking}), e non ci sono
+    connessioni in attesa di essere accettate.
+  \item[\macro{EPERM}] Le regole del firewall non consentono la connessione.
+  \item[\macro{ENOBUFS, ENOMEM}] questo spesso significa che l'allocazione
+    della memoria è limitata dai limiti sui buffer dei socket, non dalla
+    memoria di sistema.
+  \end{errlist}
+  Inoltre possono essere restituiti gli errori di rete relativi al nuovo
+  socket come: \macro{EMFILE}, \macro{EINVAL}, \macro{ENOSR}, \macro{ENOBUFS},
+  \macro{EFAULT}, \macro{EPERM}, \macro{ECONNABORTED},
+  \macro{ESOCKTNOSUPPORT}, \macro{EPROTONOSUPPORT}, \macro{ETIMEDOUT},
+  \macro{ERESTARTSYS}.}
+\end{prototype}
+
+La funzione può essere usata solo con socket che supportino la connessione
+(cioè di tipo \macro{SOCK\_STREAM}, \macro{SOCK\_SEQPACKET} o
+\macro{SOCK\_RDM}). Per alcuni protocolli che richiedono una conferma
+esplicita della connessione, (attualmente in Linux solo DECnet ha questo
+comportamento), la funzione opera solo l'estrazione dalla coda delle
+connessioni, la conferma della connessione viene fatta implicitamente dalla
+prima chiamata ad una \func{read} o una \func{write} mentre il rifiuto della
+connessione viene fatto con la funzione \func{close}.
+
+È da chiarire che Linux presenta un comportamento diverso nella gestione degli
+errori rispetto ad altre implementazioni dei socket BSD, infatti la funzione
+\func{accept} passa gli errori di rete pendenti sul nuovo socket come codici
+di errore per \func{accept}. Inoltre la funzione non fa ereditare ai nuovi
+socket flag come \macro{O\_NONBLOCK}, che devono essere rispecificati volta
+volta, questo è un comportamento diverso rispetto a quanto accade con BSD e
+deve essere tenuto in conto per scrivere programmi portabili.
+
+I due argomenti \var{cliaddr} e \var{addrlen} (si noti che quest'ultimo
+è passato per indirizzo per avere indietro il valore) sono usati per ottenere
+l'indirizzo del client da cui proviene la connessione. Prima della chiamata
+\var{addrlen} deve essere inizializzato alle dimensioni della struttura il
+cui indirizzo è passato come argomento in \var{cliaddr}, al ritorno della
+funzione \var{addrlen} conterrà il numero di byte scritti dentro
+\var{cliaddr}. Se questa informazione non interessa basterà inizializzare a
+\macro{NULL} detti puntatori.
+
+Se la funzione ha successo restituisce il descrittore di un nuovo socket
+creato dal kernel (detto \textit{connected socket}) a cui viene associata la
+prima connessione completa (estratta dalla relativa coda, vedi
+\secref{sec:TCPel_func_listen}) che il client TCP ha effettuato verso il
+socket \var{sockfd}. Quest'ultimo (detto \textit{listening socket}) è quello
+creato all'inizio e messo in ascolto con \func{listen}, e non viene toccato
+dalla funzione.  Se non ci sono connessioni pendenti da accettare la funzione
+mette in attesa il processo\footnote{a meno che non si sia imopstato il socket
+  per essere non bloccante (vedi \secref{sec:file_noblocking}), nel qual caso
+  ritorna con l'errore \macro{EAGAIN}.  Torneremo su questa modalità di
+  operazione in \secref{sec:xxx_sock_noblock}.}  fintanto che non ne arriva
+una.
+Il meccanismo di funzionamento di \func{accept} è essenziale per capire il
+funzionamento di un server: in generale infatti c'è sempre un solo socket in
+ascolto, che resta per tutto il tempo nello stato \texttt{LISTEN}, mentre le
+connessioni vengono gestite dai nuovi socket ritornati da \func{accept} che
+si trovano automaticamente nello stato \texttt{ESTABLISHED} e utilizzati fino
+alla chiusura della connessione che avviene su di essi.  Si può riconoscere
+questo schema anche nell'esempio elementare in \figref{fig:net_serv_code} dove
+per ogni connessione il socket creato da \func{accept} viene chiuso dopo
+l'invio dei dati.
+
+
+\subsection{La funzione \func{close}}
+\label{sec:TCPel_func_close}
+
+La funzione standard unix \func{close} (vedi \secref{sec:file_close}) che si
+usa sui file può essere usata con lo stesso effetto anche sui socket
+descriptor.
+
+L'azione standard di questa funzione quando applicata a socket è di marcarlo
+come chiuso e ritornare immediatamente al processo. Una volta chiamata il
+socket descriptor non è più utilizzabile dal processo e non può essere usato
+come argomento per una \func{write} o una \func{read} (anche se l'altro
+capo della connessione non avesse chiuso la sua parte).  Il kernel invierà
+comunque tutti i dati che ha in coda prima di iniziare la sequenza di chiusura.
+
+Vedremo più avanti in \secref{sec:TCPadv_so_linger} come è possibile cambiare
+questo comportamento, e cosa deve essere fatto perché il processo possa
+assicurarsi che l'altro capo abbia ricevuto tutti i dati.
+
+Come per i file anche per i socket descriptor viene mantenuto un numero di
+riferimenti, per cui se più di un processo ha lo stesso socket aperto
+l'emissione del FIN e la sequenza di chiusura di TCP non viene innescata
+fintanto che il numero di riferimenti non si annulla. Questo è il
+comportamento normale che ci si aspetta in un'applicazione client/server quale
+quella che illustreremo in \secref{sec:TCPel_cunc_serv}.
+
+Per attivare immediatamente l'emissione del FIN e la sequenza di chiusura si
+può usare la funzione \func{shutdown} su cui torneremo in seguito. 
+
+
+
+\section{I server concorrenti su TCP}
+\label{sec:TCPel_cunc_serv}
+
+Il server \texttt{daytime} dell'esempio in \secref{sec:net_cli_sample} è un
+tipico esempio di server iterativo, in cui viene servita una richiesta alla
+volta; in generale però, specie se il servizio è più complesso e comporta uno
+scambio di dati più sostanzioso di quello in questione, non è opportuno
+bloccare un server nel servizio di un client per volta; per questo si ricorre
+alle capacità di multitasking del sistema.
+
+Il modo più immediato per creare un server concorrente è allora quello di
+usare la funzione \func{fork} per far creare al server per ogni richiesta da
+parte di un client un processo figlio che si incarichi della gestione della
+comunicazione.
+
+
+\subsection{Un esempio di server \textit{daytime} concorrente}
+\label{sec:TCPel_cunc_daytime}
+
+Per illustrare il meccanismo usato in generale per creare un server
+concorrente abbiamo riscritto il server \texttt{daytime} dell'esempio
+precedente in forma concorrente, inserendo anche una opzione per la stampa
+degli indirizzi delle connessioni ricevute.
+
+In \figref{fig:TCPel_serv_code} è mostrato un estratto del codice, in cui si
+sono tralasciati il trattamento delle opzioni e le parti rimaste invariate
+rispetto al precedente esempio. Al solito il sorgente completo del server
+\file{ElemDaytimeTCPCuncServ.c} è allegato nella directory dei sorgenti.
+
+\begin{figure}[!htb]
+  \footnotesize
+  \begin{lstlisting}{}
+#include <sys/types.h>   /* predefined types */
+#include <unistd.h>      /* include unix standard library */
+#include <arpa/inet.h>   /* IP addresses conversion utiliites */
+#include <sys/socket.h>  /* socket library */
+#include <stdio.h>       /* include standard I/O library */
+#include <time.h>
+
+int main(int argc, char *argv[])
+{
+    int list_fd, conn_fd;
+    int i;
+    struct sockaddr_in serv_add, client;
+    char buffer[MAXLINE];
+    socklen_t len;
+    time_t timeval;
+    pid_t pid;
+    int logging=0;
+     ...
+    /* write daytime to client */
+    while (1) {
+        if ( (conn_fd = accept(list_fd, (struct sockaddr *)&client, &len)) 
+             <0 ) {
+            perror("accept error");
+            exit(-1);
+        }
+        /* fork to handle connection */
+        if ( (pid = fork()) < 0 ){
+            perror("fork error");
+            exit(-1);
+        }
+        if (pid == 0) {                 /* child */
+            close(list_fd);
+            timeval = time(NULL);
+            snprintf(buffer, sizeof(buffer), "%.24s\r\n", ctime(&timeval));
+            if ( (write(conn_fd, buffer, strlen(buffer))) < 0 ) {
+                perror("write error");
+                exit(-1);
+            }
+            if (logging) {
+                inet_ntop(AF_INET, &client.sin_addr, buffer, sizeof(buffer));
+                printf("Request from host %s, port %d\n", buffer,
+                       ntohs(client.sin_port));
+            }
+            close(conn_fd);
+            exit(0);
+        } else {                        /* parent */
+            close(conn_fd);
+        }
+    }
+    /* normal exit, never reached */
+    exit(0);
+}
+  \end{lstlisting}
+  \caption{Esempio di codice di un server concorrente elementare per il 
+    servizio daytime.}
+  \label{fig:TCPel_serv_code}
+\end{figure}
+
+Come si può vedere (alle linee \texttt{\small 21--25}) la funzione
+\func{accept} stavolta è chiamata fornendo una struttura di indirizzi in cui
+saranno ritornati numero IP e porta da cui il client effettua la connessione,
+che stamperemo, se avremo abilitato il logging, sullo standard output
+(\texttt{\small 39--43}). 
+
+Quando \func{accept} ritorna il server chiama la funzione \func{fork}
+(\texttt{\small 26--30}) per creare il processo figlio che effettuerà tutte le
+operazioni relative a quella connessione (\texttt{\small 31--45}), mentre il
+padre resterà in attesa di ulteriori connessioni. 
+
+Si noti come il figlio operi solo sul socket connesso, chiudendo
+immediatamente il socket \var{list\_fd}; mentre il padre continua ad operare
+solo sul socket in ascolto chiudendo \var{sock\_fd} dopo ciascuna
+\func{accept}. Per quanto abbiamo detto in \secref{sec:TCPel_func_close}
+queste due chiusure non causano l'innesco della sequenza di chiusura perché il
+numero di riferimenti non si è annullato.
+
+Infatti subito dopo la creazione del socket \var{list\_fd} ha una
+referenza, e lo stesso vale per \var{sock\_fd} dopo il ritorno di
+\func{accept}, ma dopo la fork i descrittori vengono duplicati nel padre e
+nel figlio per cui entrambi i socket si trovano con due referenze. Questo fa
+si che quando il padre chiude \var{sock\_fd} esso resta con una referenza
+da parte del figlio, e sarà definitivamente chiuso solo quando quest'ultimo,
+dopo aver completato le sue operazioni, chiamerà la funzione \func{close}.
+
+In realtà per il figlio non sarebbero necessarie nessuna delle due chiamate a
+\func{close} in quanto nella \func{exit} tutti i file ed i socket vengono
+chiusi, ma si è preferito effettuare la chiusura esplicitamente per avere una
+maggiore chiarezza del codice ed evitare possibili errori.
+
+Si noti come sia essenziale che il padre chiuda ogni volta il socket connesso
+dopo la \func{accept}; se così non fosse nessuno di questi socket sarebbe
+effettivamente chiuso dato che alla chiusura da parte del figlio resterebbe
+ancora un riferimento. Si avrebbero così due effetti, il padre potrebbe
+esaurire i descrittori disponibili (che sono un numero limitato per ogni
+processo) e soprattutto nessuna delle connessioni con i client verrebbe
+chiusa.
+
+
+\subsection{Le funzioni \func{getsockname} e \func{getpeername}}
+\label{sec:TCPel_get_names}
+
+Queste due funzioni vengono usate per ottenere la socket pair associata ad un
+certo socket; la prima restituisce l'indirizzo locale, la seconda quello
+remoto. 
+
+\begin{prototype}{sys/socket.h}
+  {int getsockname(int sockfd, struct sockaddr * name, socklen\_t * namelen)}
+  Legge l'indirizzo locale del socket \param{sockfd} nella struttura
+  \param{name}.
+
+\bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
+  errore. I codici di errore restituiti in \var{errno} sono i seguenti:
+  \begin{errlist}
+  \item[\macro{EBADF}] l'argomento \var{sockfd} non è un file descriptor
+    valido.
+  \item[\macro{ENOTSOCK}] l'argomento \var{sockfd} non è un socket.
+  \item[\macro{ENOBUFS}] non ci sono risorse sufficienti nel sistema per
+    eseguire l'operazione.
+  \item[\macro{EFAULT}] l'argomento \var{name} punta al di fuori dello
+    spazio di indirizzi del processo.
+  \end{errlist}}
+\end{prototype}
+
+La funzione \func{getsockname} si usa tutte le volte che si vuole avere
+l'indirizzo locale di un socket; ad esempio può essere usata da un client (che
+usualmente non chiama \func{bind}) per ottenere numero IP e porta locale
+associati al socket restituito da una \func{connect}, o da un server che ha
+chiamato \func{bind} su un socket usando 0 come porta locale per ottenere il
+numero di porta effimera assegnato dal kernel. 
+
+Inoltre quando un server esegue una \func{bind} su un indirizzo generico, se
+chiamata dopo il completamento di una connessione sul socket restituito da
+\func{accept}, restituisce l'indirizzo locale che il kernel ha assegnato a
+quella connessione.
+
+\begin{prototype}{sys/socket.h}
+  {int getpeername(int sockfd, struct sockaddr * name, socklen\_t * namelen)}
+  Legge l'indirizzo remoto del socket \param{sockfd} nella struttura
+  \param{name}.
+  
+  \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
+    errore. I codici di errore restituiti in \var{errno} sono i seguenti:
+  \begin{errlist}
+  \item[\macro{EBADF}] l'argomento \var{sockfd} non è un file descriptor
+    valido.
+  \item[\macro{ENOTSOCK}] l'argomento \var{sockfd} non è un socket.
+  \item[\macro{ENOTCONN}] il socket non è connesso.
+  \item[\macro{ENOBUFS}] non ci sono risorse sufficienti nel sistema per
+    eseguire l'operazione.
+  \item[\macro{EFAULT}] l'argomento \var{name} punta al di fuori dello
+    spazio di indirizzi del processo.
+  \end{errlist}}
+\end{prototype}
+
+
+La funzione \func{getpeername} si usa tutte le volte che si vuole avere
+l'indirizzo remoto di un socket. 
+
+Ci si può chiedere a cosa serva questa funzione dato che dal lato client
+l'indirizzo remoto è sempre noto quando si esegue la \func{connect} mentre
+dal lato server si possono usare, come si è fatto nell'esempio precedente, i
+valori di ritorno di \func{accept}.
+
+In generale però questa ultima possibilità è sempre possibile. In particolare
+questo avviene quando il server invece di far gestire la connessione
+direttamente a un processo figlio, come nell'esempio precedente, lancia un
+opportuno programma per ciascuna connessione usando \func{exec} (questa ad
+esempio è la modalità con cui opera il \textsl{super-server} \cmd{inetd}
+che gestisce tutta una serie di servizi lanciando per ogni connessione
+l'opportuno server).
+
+In questo caso benché il processo figlio abbia una immagine della memoria che
+è copia di quella del processo padre (e contiene quindi anche la struttura
+ritornata da \func{accept}), all'esecuzione di \func{exec} viene caricata
+in memoria l'immagine del programma eseguito che a questo punto perde ogni
+riferimento. Il socket descriptor però resta aperto. Allora se una opportuna
+convenzione è seguita per rendere noto al programma eseguito qual'è il socket
+connesso (\cmd{inetd} ad esempio fa sempre in modo che i file descriptor 0,
+1 e 2 corrispondano al socket connesso) quest'ultimo potrà usare la funzione
+\func{getpeername} per determinare l'indirizzo remoto del client.
 
-\subsection{Le porte}
+Infine è da chiarire (si legga la pagina di manuale) che, come per
+\func{accept}, il terzo parametro, che è specificato dallo standard POSIX.1g
+come di tipo \code{socklen\_t *} in realtà deve sempre corrispondere ad un
+\ctyp{int *} come prima dello standard perché tutte le implementazioni dei
+socket BSD fanno questa assunzione.
 
 
 
+%%% Local Variables: 
+%%% mode: latex
+%%% TeX-master: "gapil"
+%%% End: