Sistemati i conflitti e scritta parte di accept.
[gapil.git] / elemtcp.tex
index 3f256c875ef8838d0e1ecf9957e3f72b8c5fd71c..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,18 +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}
@@ -243,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
@@ -290,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
@@ -330,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
@@ -339,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
@@ -423,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
@@ -507,9 +507,12 @@ 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 nella
-programmazione di rete consideriamo cosa accade con una serie di esempi, se
-esguiamo un \texttt{netstat} su una macchina di prova (che supponiamo avere
+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_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
 indirizzo 195.110.112.152) potremo avere un risultato del tipo:
 \begin{verbatim}
 Active Internet connections (servers and established)
@@ -518,8 +521,8 @@ 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 un server ssh, un server di posta e un DNS per il caching
-locale. 
+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 è
@@ -565,12 +568,12 @@ tcp        0      0 195.110.112.152:22      192.84.146.100:21100    ESTABLISHED
 
 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, ma ha specificato l'indirizzo locale, e che corrisponde al socket
-con cui il processo figlio gestisce la connessione mentre il padre resta in
-ascolto.
+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 lanciamo una seconda volta il client ssh per una seconda
-conessione quello che otterremo sarà qualcosa del genere:
+Se a questo punto lanciamo un'altra volta il client ssh per una seconda
+conessione 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      
@@ -580,17 +583,17 @@ 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è al client sarà stata assegnata un'altra porta effimera e con questa sarà
-aperta la connessione, ed un nuovo processo figlio sarà creato per gestirla.
+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 due connessioni, 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.
+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{Le funzioni dei socket TCP}
@@ -598,14 +601,14 @@ porta remota 21100 vanno al primo figlio e quelli che arrivano alla porta
 
 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.
@@ -619,38 +622,120 @@ 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}}
+\label{sec:TCPel_func_bind}
+
+
+La funzione \texttt{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 \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 \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{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{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
+nota che assegnano all'avvio, se questo non viene fatto è il kernel a
+scegliere una porta effimera quando vengono eseguite la funzioni
+\texttt{connect} o \texttt{listen}, ma se questo è normale per il client non
+lo è per il server\footnote{un'eccezione a tutto ciò 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 \texttt{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 orgine 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
+\texttt{INADDR\_ANY}, il cui valore, come visto anche negli esempi precedenti
+è 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 */
+\end{verbatim}
+
+Si noti che si è usato \texttt{htonl} per assegnare il valore
+\texttt{INADDR\_ANY}; benché essendo questo pari a zero il riordinamento sia
+inutile; ma dato che tutte le constanti \texttt{INADDR\_} sono definite
+secondo l'ordinamento della macchina è buona norma usare sempre la funzione
+\texttt{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 \texttt{netinet/in.h} è definita una
+variabile \texttt{in6addr\_any} (dichiarata come \texttt{extern}, ed
+inizializzata dal sistema al valore \texttt{IN6ADRR\_ANY\_INIT}) che permette
+di effettuare una assegnazione del tipo:
+\begin{verbatim}
+   serv_add.sin6_addr = in6addr_any;   /* connect from anywhere */
+\end{verbatim}
+
 
 \subsection{La funzione \texttt{connect}}
 \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}
+  codici di errore:
+  \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.
-  \item \texttt{ENOTSOCK} Il file descriptor non è associato ad un socket
+  \item \texttt{ENOTSOCK} Il file descriptor non è associato ad un socket.
   \item \texttt{EISCONN} Il socket è già connesso.
   \item \texttt{ECONNREFUSED} Non c'è nessuno in ascolto sull'indirizzo remoto.
   \item \texttt{ETIMEDOUT} Si è avuto timeout durante il tentativo di
     connessione.
-  \item \texttt{ENETUNREACH} La rete non è rggiungibile/
+  \item \texttt{ENETUNREACH} La rete non è raggiungibile.
   \item \texttt{EADDRINUSE} L'indirizzo locale è in uso.
   \item \texttt{EINPROGRESS} Il socket è non bloccante e la connessione non
     può essere conclusa immediatamente.
@@ -659,36 +744,39 @@ connessione con un server TCP, il prototipo della funzione, definito in
   \item \texttt{EAGAIN} Non ci sono più porte locali libere. 
   \item \texttt{EAFNOSUPPORT} L'indirizzo non ha una famiglia di indirizzi
     corretta nel relativo campo.
-  \item \texttt{EACCESS, EPERM} 
-  \end{itemize}
-\end{itemize}
+  \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{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
-un errore. Le possibili cause di errore sono molteplici (e brevemente
-riassunte sopra), in particolare le principali sono:
+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 Se il client non riceve risposta al SYN l'errore restituito è
+\item Il client non riceve risposta al SYN: l'errore restituito è
   \texttt{ETIMEDOUT}. Stevens riporta che BSD invia un primo SYN alla chiamata
   di \texttt{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
   \texttt{sysctl} che attraverso il filesystem \texttt{/proc} scrivendo il
-  valore voluto in \texttt{/proc/sys/net/ipv4/tcp_syn_retries}. Il valore di
+  valore voluto in \texttt{/proc/sys/net/ipv4/tcp\_syn\_retries}. Il valore di
   default per la ripetizione dell'invio è di 5 volte, che comporta un timeout
   dopo circa 180 secondi.
 %
 % Le informazioni su tutte le opzioni settabili via /proc stanno in
 % linux/Documentation/networking/ip-sysctl.txt
 %
-\item Se il client riceve come risposta al SYN un RST significa che non c'è
+\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 probablmente che o si è sbagliato il numero della porta o che
   non è stato avviato il server), questo è un errore fatale e la funzione
@@ -700,28 +788,209 @@ riassunte sopra), in particolare le principali sono:
   quando arriva un SYN per una porta che non ha nessun server in ascolto,
   quando il TCP abortisce una connessione in corso, quandi 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. 
   
+\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'emmissione 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
+  \texttt{ENETUNREACH}.
+   
 \end{enumerate}
 
-\subsection{La funzione \texttt{bind}}
-\label{sec:TCPel_func_bind}
+Se si fa riferimento al diagramma degli stati del TCP riportato in
+\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
+socket non è più utilizzabile e deve essere chiuso.
 
+Si noti infine che con la funzione \texttt{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à contentente indirizzo e porta
+locale viene lasciata all'assegnazione automatica del kernel, e non è
+necessario effettuare una \texttt{bind}.
 
 
 \subsection{La funzione \texttt{listen}}
 \label{sec:TCPel_func_listen}
 
-\subsection{La funzione \texttt{accept}}
-\label{sec:TCPel_func_accept}
-
+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}. 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} 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}
 
-\section{Una semplice implementazione del servizio \textt{echo} su TCP}
-\label{sec:TCPel_echo_example}
+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