Sistemati i conflitti e scritta parte di accept.
[gapil.git] / elemtcp.tex
index 94612fa7759e2fd4415015a93c33a0dca7adfaf2..9eab58a2adf71cb073b6562dd5c17e3740f31069 100644 (file)
@@ -3,9 +3,10 @@
 
 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_serv_sample}), previa una descrizione delle principali
-caratteristiche del funzionamento di una connessione TCP.
+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.
 
 La seconda parte del capitolo sarà poi dedicata alla scrittura di una prima
 semplice applicazione client/server completa, che implementi il servizio
@@ -31,10 +32,10 @@ l'uso del programma \texttt{netstat}.
 Il processo che porta a creare una connessione TCP è chiamato \textit{three
   way handushake}; la successione tipica degli eventi (la stessa che si
 verifica utilizzando il codice dei due precedenti esempi elementari
-\ref{fig:net_cli_code} e \ref{fig:net_serv_code}) che porta alla creazione di
-una connessione è la seguente:
+\figref{fig:net_cli_code} e \figref{fig:net_serv_code}) che porta alla
+creazione di una connessione è la seguente:
  
-\begin{itemize}
+\begin{enumerate}
 \item Il server deve essere preparato per accettare le connessioni in arrivo;
   il procedimento si chiama \textsl{apertura passiva} del socket (in inglese
   \textit{passive open}); questo viene fatto chiamando la sequenza di funzioni
@@ -55,7 +56,7 @@ una connessione 
     \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
+    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 \texttt{SYN}) e le opzioni di TCP.
   
@@ -70,7 +71,7 @@ una connessione 
   \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} 
+\end{enumerate} 
 
 Il procedimento viene chiamato \textit{three way handshake} dato che per
 realizzarlo devono essere scambiati tre segmenti.  In \nfig\ si è
@@ -126,7 +127,7 @@ regolare la connessione. Normalmente vengono usate le seguenti opzioni:
   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
+\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
@@ -164,8 +165,8 @@ elevati. In ogni caso linux supporta pienamente entrambe le opzioni.
 
 Mentre per creare una connessione occorre un interscambio di tre segmenti, la
 procedura di chiusura ne richede quattro; ancora una volta si può fare
-riferimento al codice degli esempi \ref{fig:net_cli_code} e
-\ref{fig:net_serv_code}, in questo caso la successione degli eventi è la
+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}
@@ -185,7 +186,7 @@ seguente:
 \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}
@@ -218,17 +219,17 @@ pi
 
 La emissione del FIN avviene quando il socket viene chiuso, questo però non
 avviene solo per la chiamata della funzione \texttt{close} (come in
-\ref{fig:net_serv_code}), ma anche alla terminazione di un processo (come in
-\ref{fig:net_cli_code}). Questo vuol dire ad esempio che se un processo viene
-terminato da un segnale tutte le connessioni aperte verranno chiuse.
+\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
-in \ref{sec:TCPel_echo_example}) sia 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 da \ref{fig:net_serv_code}), e
-benché quello del client sia il caso più comune ci sono alcuni servizi, il
-principale dei quali è l'HTTP, per i quali è il server ad effettuare la
-chiusura attiva.
+in \secref{sec:TCPel_echo_example}) sia 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 da
+\figref{fig:net_serv_code}), e benché quello del client sia il caso più comune
+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}
 \label{sec:TCPel_conn_dia}
@@ -242,26 +243,26 @@ che vengono riportati del comando \texttt{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 \ref{cha:tcp_protocol}, ma per una trattazione esauriente il miglior
+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 è \textsl{CLOSED}; quando una
+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 \textsl{SYN\_SENT}; quando il TCP riceve la risposta del SYN$+$ACK
-emette un ACK e passa allo stato \textsl{ESTABLISHED}; questo è 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 \textsl{CLOSED} allo
-stato \textsl{LISTEN} in cui vengono accettate le connessioni.
+passiva è quello di portare il socket dallo stato \texttt{CLOSED} allo
+stato \texttt{LISTEN} in cui vengono accettate le connessioni.
 
-Dallo stato \textsl{ESTABLISHED} si può uscire in due modi; se un'applicazione
+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 \textsl{FIN\_WAIT\_1}; se invece
-l'applicazione riceve un FIN nello stato \textsl{ESTABLISHED} (chiusura
-passiva) la transizione è verso lo stato \textsl{CLOSE\_WAIT}.
+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 \nfig\ è riportato lo schema dello scambio dei pacchetti che avviene per
 una un esempio di connessione, insieme ai vari stati che il protocollo viene
@@ -289,9 +290,9 @@ 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 \ref{sec:TCPel_conn_term}; si noti che il capo della
+secondo quanto visto in \secref{sec:TCPel_conn_term}; si noti che il capo della
 connessione che esegue la chiusura attiva entra nello stato
-\textsl{TIME\_WAIT} su cui torneremo fra poco.
+\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
@@ -329,7 +330,7 @@ La MSL 
 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 \ref{sec:appA_xxx}), e viene decrementato ad
+IP (per maggiori dettagli vedi \secref{sec:appA_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
@@ -338,16 +339,16 @@ pi
 
 Ogni implementazione del TCP deve scegliere un valore per la MSL (l'RFC1122
 raccomanda 2 minuti, linux usa 30 secondi), questo comporta una durata dello
-stato \textsl{TIME\_WAIT} che a seconda delle implementazioni può variare fra
+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{itemize}
+\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{itemize}
+\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
@@ -422,7 +423,7 @@ In un ambiente multitasking in un dato momento pi
 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 \ref{sec:sock_sa_ipv4} e \ref{sec:sock_sa_ipv6} pure delle strutture
+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
@@ -508,7 +509,7 @@ campi \textit{Local Address} e \textit{Foreing Address}.
 
 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
-\ref{sec:TCPel_echo_example}) esaminaremo cosa accade con le connessioni nel
+\secref{sec:TCPel_echo_example}) esaminaremo cosa accade con le connessioni nel
 caso di un server TCP che deve gestire connessioni multiple.
 
 Se esguiamo un \texttt{netstat} su una macchina di prova (che supponiamo avere
@@ -600,14 +601,14 @@ alla porta 21101 al secondo.
 
 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
-\ref{sec:net_cli_sample} e \ref{sec:net_serv_sample}) con l'eccezione della
-funzione \texttt{socket} che è già stata esaminata in dettaglio in
-\ref{sec:sock_socket}.
+\secref{sec:net_cli_sample} e \secref{sec:net_serv_sample}) con l'eccezione
+della funzione \texttt{socket} che è già stata esaminata in dettaglio in
+\secref{sec:sock_socket}.
 
 In \nfig\ 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 Cap.~\ref{cha:network} si assume che sia il
+con gli esempi elementari del Cap.~\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.
@@ -621,7 +622,7 @@ risponder
 \end{figure}
 
 Useremo questo schema per l'esempio di implementazione del servizio
-\texttt{echo} che illustreremo in \ref{sec:TCPel_echo_example}. 
+\texttt{echo} che illustreremo in \secref{sec:TCPel_echo_example}. 
 
 
 \subsection{La funzione \texttt{bind}}
@@ -633,29 +634,27 @@ cio
 server per specificare la porta (e gli eventuali indirizzi locali) su cui poi
 ci si porrà in ascolto.
 
-Il prototipo della funzione, definito in \texttt{sys/socket.h}, è il seguente:
+Il prototipo della funzione è il seguente:
 
-\begin{itemize}
-\item \texttt{int bind(int sockfd, const struct sockaddr *serv\_addr,
-    socklen\_t addrlen) }
+\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 \texttt{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 \ref{sec:sock_sockaddr}.
+  contiene, secondo quanto già trattato in \secref{sec:sock_sockaddr}.
 
   La funzione restituisce zero in caso di successo e -1 per un errore, in caso
   di errore. La variabile \texttt{errno} viene settata secondo i seguenti
   codici di errore:
-  \begin{itemize}
+  \begin{errlist}
   \item \texttt{EBADF} Il file descriptor non è valido.
   \item \texttt{EINVAL} Il socket ha già un indirizzo assegnato.
   \item \texttt{ENOTSOCK} Il file descriptor non è associato ad un socket.
   \item \texttt{EACCESS} Si è cercato di usare un indirizzo riservato senza
     essere root. 
-  \end{itemize}
-
-\end{itemize}
+  \end{errlist}
+\end{prototype}
 
 Con il TCP la chiamata \texttt{bind} permette di specificare l'indirizzo, la
 porta, entrambi o nessuno dei due. In genere i server utilizzano una porta
@@ -685,7 +684,7 @@ client.
 
 Per specificare un indirizzo generico con IPv4 si usa il valore
 \texttt{INADDR\_ANY}, il cui valore, come visto anche negli esempi precedenti
-è pari a zero, nell'esempio \ref{fig:net_serv_sample} si è usata
+è pari a zero, nell'esempio \figref{fig:net_serv_sample} si è usata
 un'assegnazione immediata del tipo:
 \begin{verbatim}
    serv_add.sin_addr.s_addr = htonl(INADDR_ANY);   /* connect from anywhere */
@@ -714,22 +713,20 @@ di effettuare una assegnazione del tipo:
 \label{sec:TCPel_func_connect}
 
 La funzione \texttt{connect} è usata da un client TCP per stabilire la
-connessione con un server TCP, il prototipo della funzione, definito in
-\texttt{sys/socket.h}, è il seguente:
+connessione con un server TCP, il prototipo della funzione è il seguente:
 
-\begin{itemize}
-\item \texttt{int connect(int sockfd, const struct sockaddr *serv\_addr,
-    socklen\_t addrlen) }
+\begin{prototype}{sys/socket.h}
+{int connect(int sockfd, const struct sockaddr *serv\_addr, socklen\_t addrlen)}
   
   Il primo argomento è un file descriptor ottenuto da una precedente chiamata
   a \texttt{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 \ref{sec:sock_sockaddr}.
+  socket, già descritta in \secref{sec:sock_sockaddr}.
 
   La funzione restituisce zero in caso di successo e -1 per un errore, in caso
   di errore. La variabile \texttt{errno} viene settata secondo i seguenti
   codici di errore:
-  \begin{itemize}
+  \begin{errlist}
   \item \texttt{EBADF} Il file descriptor non è valido.
   \item \texttt{EFAULT} L'indirizzo della struttura di indirizzi è al di fuori
     dello spazio di indirizzi dell'utente.
@@ -750,13 +747,13 @@ connessione con un server TCP, il prototipo della funzione, definito in
   \item \texttt{EACCESS, EPERM} Si è tentato di eseguire una connessione ad un
     indirizzo broacast senza che il socket fosse stato abilitato per il
     broadcast.
-  \end{itemize}
-\end{itemize}
+  \end{errlist}
+\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 \ref{sec:net_cli_sample} usando le funzioni illustrate in
-\ref{sec:sock_addr_func}.
+nell'esempio \secref{sec:net_cli_sample} usando le funzioni illustrate in
+\secref{sec:sock_addr_func}.
 
 Nel caso di socket TCP la funzione \texttt{connect} avvia il three way
 handshake, e ritorna solo quando la connessione è stabilita o si è verificato
@@ -802,7 +799,7 @@ da errori o problemi nella chiamata della funzione sono le seguenti:
 \end{enumerate}
 
 Se si fa riferimento al diagramma degli stati del TCP riportato in
-\ref{fig:appB:tcp_state_diag} la funzione \texttt{connect} porta un socket
+\figref{fig:appB:tcp_state_diag} la funzione \texttt{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
@@ -821,23 +818,179 @@ necessario effettuare una \texttt{bind}.
 La funzione \texttt{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}.
-
-\begin{prototype}{int listen(int sockfd, int backlog)}
+\texttt{CLOSED} a quello \texttt{LISTEN}. In genere si chiama la funzione in
+un server dopo le chiamate a \texttt{socket} e \texttt{bind} e prima della
+chiamata ad \texttt{accept}. Il prototipo della funzione come definito dalla
+man page è:
+
+\begin{prototype}{sys/socket.h}{int listen(int sockfd, int backlog)}
+  La funzione pone il socket specificato da \texttt{sockfd} in modalità
+  passiva e predispone una coda per le connessioni in arrivo di lunghezza pari
+  a \texttt{backlog}. La funzione si può applicare solo a socket di tipo
+  \texttt{SOCK\_STREAM} o \texttt{SOCK\_SEQPACKET}.
+
+  La funzione restituisce 0 in caso di successo e -1 in caso di errore. I
+  codici di errore restituiti in \texttt{errno} sono i seguenti:
   \begin{errlist}
   \item \texttt{EBADF} L'argomento \texttt{sockfd} non è un file descriptor
     valido.
   \item \texttt{ENOTSOCK} L'argomento \texttt{sockfd} non è un socket.
-  \item \texttt{EOPNOTSUPP} The socket is not of a type that supports the lis­
-    ten operation.
+  \item \texttt{EOPNOTSUPP} Il socket è di un tipo che non supporta questa
+    operazione.
   \end{errlist}
 \end{prototype}
 
 
+Il parametro \texttt{backlog} indica il numero massimo di connessioni pendenti
+accettate; se esso viene ecceduto il client riceverà una errore di tipo
+\texttt{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 una entrata per ciascun SYN arrivato per il quale si
+  sta attendendo la conclusione del three-way handshake. Questi socket sono
+  tutti nello stato \texttt{SYN\_RECV}.
+\item Una coda delle connessioni complete (\textit{complete connection queue}
+  che contiene una entrata per ciascuna connessione per le quali il three-way
+  handshake è stato completato ma ancora \texttt{accept} non è ritornata.
+\end{enumerate}
+
+Lo schema di funzionamento è descritto in \nfig, 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 \texttt{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 \texttt{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.
+
+Ma in linux il significato di questo valore è cambiato a partire dal kernel
+2.2 per prevenire l'attacco chiamato \texttt{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 la coda delle connessioni incomplete viene saturata, impedendo di
+fatto le connessioni.
+
+Per ovviare a questo il significato del \texttt{backlog} è stato cambiato a
+significare la lunghezza della coda delle connessioni complete. La lunghezza
+della coda delle connessioni incomplete può essere ancora controllata usando
+la \texttt{sysctl} o scrivendola direttamente in
+\texttt{/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 \texttt{/proc/sys/net/ipv4/tcp\_syncookies}) questo valore
+viene ignorato e non esiste più un valore massimo.
+
+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 dagli anni '80 e con server web che possono sopportare diversi
+milioni di connessioni al giorno un tale valore non è più adeguato. Non esiste
+comunque una risposta univoca per la scelta del valore, per questo non
+conviene specificare questo valore con una costante (il cui cambiamento
+richiederebbe la ricompilazione del server) ma usare piuttosto una variabile
+di ambiente (vedi \secref{sec:xxx_env_var}).  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 la ragione della coda è quella
+di gestire il caso in cui il server è occupato fra chiamate successive alla
+\texttt{accept} (per cui la coda più occupata sarebbe quella delle connessioni
+compeltate), ma è invece necessaria a gestire la presenza di un gran numero di
+SYN in attesa di completare il three-way handshake.
+
+Come accennato nel caso del TCP se un SYN arriva con tutte le code piene, il
+pacchetto sarà ignorato. Questo viene fatto perché la condizione delle code
+piene è transitoria, e se il client ristrasmette il SYN è probabile che
+passato un po' di tempo possa trovare lo spazio per una nuova connessione. Se
+invece si rispondesse con un RST la \texttt{connect} del client ritornerebbe
+con una condizione di errore, mentre questo è il tipico caso in cui è si può
+lasciare la gestione della connessione alla ritrasmissione prevista dal
+protocollo TCP.
+
+
 
 \subsection{La funzione \texttt{accept}}
 \label{sec:TCPel_func_accept}
 
+La funzione \texttt{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 listen(int sockfd, struct sockaddr *addr, socklen\_t *addrlen)}  
+  La funzione estrae la prima connessione completa relativa al socket
+  \texttt{sockfd} in attesa sulla coda delle connessioni complete che associa
+  nuovo socket con le stesse caratteristiche di \texttt{sockfd} (restituito
+  dalla funzione stessa). Il socket originale non viene toccato. Nella
+  struttura \texttt{addr} e nella variabile \texttt{addrlen} vengono
+  restituiti indirizzo e relativa lunghezza del client che si è connesso.
+  La funzione restituisce un numero di socket descriptor positivo in caso di
+  successo e -1 in caso di errore, nel qual caso la variabile \texttt{errno}
+  viene settata ai seguenti valori:
+
+  \begin{errlist}
+  \item \texttt{EBADF} L'argomento \texttt{sockfd} non è un file descriptor
+    valido.
+  \item \texttt{ENOTSOCK} L'argomento \texttt{sockfd} non è un socket.
+  \item \texttt{EOPNOTSUPP} Il socket è di un tipo che non supporta questa
+    operazione.    
+  \item \texttt{EAGAIN} or \item \texttt{EWOULDBLOCK} Il socket è stato
+    settato come non bloccante, e non ci sono connessioni in attesa di essere
+    accettate.              
+  \item \texttt{EFAULT} The addr parameter is not in a writable part of the
+    user address space.
+  \item \texttt{EPERM} Firewall rules forbid connection.
+    
+  \item \texttt{ENOBUFS, ENOMEM} Not enough free memory.  This often means
+    that the memory allocation is limited by the socket buffer limits, not by
+    the system memory.
+  \end{errlist}
+\end{prototype}
+
+La funzione può essere usata solo con socket che supportino la connessione
+(cioè di tipo \texttt{SOCK\_STREAM}, \texttt{SOCK\_SEQPACKET} o
+\texttt{SOCK\_RDM}). Per alcuni protocolli che richiedono una conferma
+esplicita della connessione, (attualmenente 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 \texttt{read} o una \texttt{write} mentre il rifiuto
+della connessione viene fatta con la funzione \texttt{close}.
+
+I due parametri \texttt{cliaddr} e \texttt{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
+\texttt{addrlen} deve essere inizializzato alle dimensioni della struttura il
+cui indirizzo è passato come parametro in \texttt{cliaddr}, al rientro della
+funzione \texttt{addrlen} conterrà il numero di bytes scritti dentro
+\texttt{cliaddr}.
+
+Se la funzione ha successo restituisce un nuovo socket descriptor, detto
+\textit{connected socket}, su cui è agganciata la connessione che il client
+TCP ha effettuato verso il socket \texttt{sockfd}. Quest'ultimo, che viene
+chiamato invece \textit{listening socket}, deve essere stato creato in
+precedenza e messo in ascolto con \texttt{listen}, e non viene toccato dalla
+funzione. 
+
+Questa distinzione è essenziale per capire 
+
+
 
 \section{Una semplice implementazione del servizio \texttt{echo} su TCP}
 \label{sec:TCPel_echo_example}
+
+Veniamo ora ad una applicazione