Varie correzioni da Fabio Rossi, e relative aggiunte nei ringrazimenti per
[gapil.git] / tcpsock.tex
index cec4ca845ad8e4e0bce5597e13b92c2ed6744120..78a6ce446664057d26eecd33fc6de8ea8f8fc65f 100644 (file)
@@ -1,6 +1,6 @@
 %% tcpsock.tex
 %%
-%% Copyright (C) 2000-2004 Simone Piccardi.  Permission is granted to
+%% Copyright (C) 2000-2005 Simone Piccardi.  Permission is granted to
 %% copy, distribute and/or modify this document under the terms of the GNU Free
 %% Documentation License, Version 1.1 or any later version published by the
 %% Free Software Foundation; with the Invariant Sections being "Un preambolo",
@@ -34,9 +34,11 @@ questa sezione ci concentreremo sulle modalit
 inizio e conclude una connessione e faremo inoltre un breve accenno al
 significato di alcuni dei vari \textsl{stati} ad essa associati.
 
+
 \subsection{La creazione della connessione: il \textit{three way handshake}}
 \label{sec:TCP_conn_cre}
 
+\index{\textit{three~way~handshake}|(}
 Il processo che porta a creare una connessione TCP è chiamato \textit{three
   way handshake}; la successione tipica degli eventi (e dei
 \textsl{segmenti}\footnote{Si ricordi che il segmento è l'unità elementare di
@@ -84,12 +86,12 @@ si 
 stabilisce la connessione.
 
 % Una analogia citata da R. Stevens per la connessione TCP è quella con il
-% sistema del telefono. La funzione \texttt{socket} può essere considerata
-% l'equivalente di avere un telefono. La funzione \texttt{bind} è analoga al
-% dire alle altre persone qual'è il proprio numero di telefono perché possano
-% chiamare. La funzione \texttt{listen} è accendere il campanello del telefono
-% per sentire le chiamate in arrivo.  La funzione \texttt{connect} richiede di
-% conoscere il numero di chi si vuole chiamare. La funzione \texttt{accept} è
+% sistema del telefono. La funzione \func{socket} può essere considerata
+% l'equivalente di avere un telefono. La funzione \func{bind} è analoga al
+% dire alle altre persone qual è il proprio numero di telefono perché possano
+% chiamare. La funzione \func{listen} è accendere il campanello del telefono
+% per sentire le chiamate in arrivo.  La funzione \func{connect} richiede di
+% conoscere il numero di chi si vuole chiamare. La funzione \func{accept} è
 % quando si risponde al telefono.
 
 \begin{figure}[htb]
@@ -116,6 +118,8 @@ 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 fig.~\ref{fig:TCP_close}) per l'acknowledgement di un FIN.
+\index{\textit{three~way~handshake}|)}
+
 
 \subsection{Le opzioni TCP.}
 \label{sec:TCP_TCP_opt}
@@ -267,7 +271,7 @@ passiva 
 stato \texttt{LISTEN} in cui vengono accettate le connessioni.
 
 Dallo stato \texttt{ESTABLISHED} si può uscire in due modi; se un'applicazione
-chiama la funzione \texttt{close} prima di aver ricevuto un
+chiama la funzione \func{close} prima di aver ricevuto un
 \textit{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
@@ -457,17 +461,17 @@ dall'\href{http://www.ietf.org/rfc/rfc1700.txt}{RFC~1700} che contiene
 l'elenco delle porte assegnate dalla IANA (la \textit{Internet Assigned Number
   Authority}) ma l'elenco viene costantemente aggiornato e pubblicato su
 internet (una versione aggiornata si può trovare all'indirizzo
-\texttt{ftp://ftp.isi.edu/in-notes/iana/assignements/port-numbers}); inoltre
+\href{ftp://ftp.isi.edu/in-notes/iana/assignements/port-number}
+{\texttt{ftp://ftp.isi.edu/in-notes/iana/assignements/port-numbers}}); inoltre
 in un sistema unix-like un analogo elenco viene mantenuto nel file
 \file{/etc/services}, con la corrispondenza fra i vari 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).
+\begin{enumerate*}
+\item \textsl{le porte note}. 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
@@ -479,29 +483,36 @@ nome simbolico del servizio.  I numeri sono divisi in tre intervalli:
 \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}
+\end{enumerate*}
 
 In realtà rispetto a quanto indicato
 nell'\href{http://www.ietf.org/rfc/rfc1700.txt}{RFC~1700} i vari sistemi hanno
 fatto scelte diverse per le porte effimere, in particolare in
-fig.~\ref{fig:TCP_port_alloc} sono riportate quelle di BSD 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.
+fig.~\ref{fig:TCP_port_alloc} sono riportate quelle di BSD e Linux.
 
 \begin{figure}[!htb]
   \centering
-  \includegraphics[width=15cm]{img/port_alloc}  
+  \includegraphics[width=13cm]{img/port_alloc}  
   \caption{Allocazione dei numeri di porta.}
   \label{fig:TCP_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 amministratore, per far si che
-solo l'amministratore possa allocare queste porte per far partire i relativi
-servizi.
+\textsl{porte note}). La loro caratteristica è che possono essere assegnate a
+un socket solo da un processo con i privilegi di amministratore, per far sì
+che solo l'amministratore possa allocare queste porte per far partire i
+relativi servizi.
+
+Le \textsl{glibc} definiscono (in \texttt{netinet/in.h})
+\const{IPPORT\_RESERVED} e \const{IPPORT\_USERRESERVED}, in cui la prima (che
+vale 1024) indica il limite superiore delle porte riservate, e la seconda (che
+vale 5000) il limite inferiore delle porte a disposizione degli utenti.  La
+convenzione vorrebbe che le porte \textsl{effimere} siano allocate fra questi
+due valori. Nel caso di Linux questo è vero solo in uno dei due casi di
+fig.~\ref{fig:TCP_port_alloc}, e la scelta fra i due possibili intervalli
+viene fatta dinamicamente dal kernel a seconda della memoria disponibile per
+la gestione delle relative tabelle.
 
 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
@@ -637,7 +648,7 @@ precedente in sez.~\ref{sec:sock_socket}.
 La funzione \funcd{bind} assegna un indirizzo locale ad un
 socket.\footnote{nel nostro caso la utilizzeremo per socket TCP, ma la
   funzione è generica e deve essere usata per qualunque tipo di socket
-  \texttt{SOCK\_STREAM} prima che questo possa accettare connessioni.} È usata
+  \const{SOCK\_STREAM} prima che questo possa accettare connessioni.} È 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:
@@ -705,9 +716,9 @@ Si noti che si 
 \const{INADDR\_ANY}, anche se, essendo questo nullo, il riordinamento è
 inutile.  Si tenga presente comunque che tutte le costanti \val{INADDR\_}
 (riportate in tab.~\ref{tab:TCP_ipv4_addr}) sono definite secondo
-l'\textit{endianess} della macchina, ed anche se esse possono essere
-invarianti rispetto all'ordinamento dei bit, è comunque buona norma usare
-sempre la funzione \func{htonl}.
+l'\textit{endianess}\index{\textit{endianess}} della macchina, ed anche se
+esse possono essere invarianti rispetto all'ordinamento dei bit, è comunque
+buona norma usare sempre la funzione \func{htonl}.
 
 \begin{table}[htb]
   \centering
@@ -750,12 +761,12 @@ staticamente a \const{IN6ADRR\_LOOPBACK\_INIT}.
 La funzione \funcd{connect} è usata da un client TCP per stabilire la
 connessione con un server TCP,\footnote{di nuovo la funzione è generica e
   supporta vari tipi di socket, la differenza è che per socket senza
-  connessione come quelli di tipo \texttt{SOCK\_DGRAM} la sua chiamata si
+  connessione come quelli di tipo \const{SOCK\_DGRAM} la sua chiamata si
   limiterà ad impostare l'indirizzo dal quale e verso il quale saranno inviati
-  e ricevuti i pacchetti, mentre per socket di tipo \texttt{SOCK\_STREAM} o
-  \texttt{SOCK\_SEQPACKET}, essa attiverà la procedura di avvio (nel caso del
-  TCP il \textit{three-way-handsjake}) della connessione.}  il prototipo della
-funzione è il seguente:
+  e ricevuti i pacchetti, mentre per socket di tipo \const{SOCK\_STREAM} o
+  \const{SOCK\_SEQPACKET}, essa attiverà la procedura di avvio (nel caso del
+  TCP il \index{\textit{three~way~handshake}}\textit{three way handshake})
+  della connessione.}  il prototipo della funzione è il seguente:
 \begin{prototype}{sys/socket.h}
   {int connect(int sockfd, const struct sockaddr *servaddr, socklen\_t
     addrlen)}
@@ -797,12 +808,12 @@ numero di porta del server a cui ci si vuole connettere, come mostrato
 nell'esempio sez.~\ref{sec:TCP_daytime_client}, usando le funzioni illustrate
 in sez.~\ref{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:
+Nel caso di socket TCP la funzione \func{connect} avvia il
+\index{\textit{three~way~handshake}}\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 è
   \errcode{ETIMEDOUT}. Stevens riporta che BSD invia un primo SYN alla chiamata
@@ -860,8 +871,8 @@ necessario effettuare una \func{bind}.
 La funzione \funcd{listen} serve ad usare un socket in modalità passiva, cioè,
 come dice il nome, per metterlo in ascolto di eventuali
 connessioni;\footnote{questa funzione può essere usata con socket che
-  supportino le connessioni, cioè di tipo \texttt{SOCK\_STREAM} o
-  \texttt{SOCK\_SEQPACKET}.} in sostanza l'effetto della funzione è di portare
+  supportino le connessioni, cioè di tipo \const{SOCK\_STREAM} o
+  \const{SOCK\_SEQPACKET}.} 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
@@ -897,11 +908,12 @@ infatti vengono mantenute due code:
 \begin{enumerate}
 \item La coda delle connessioni incomplete (\textit{incomplete connection
     queue} che contiene un riferimento per ciascun socket per il quale è
-  arrivato un SYN ma il \textit{three way handshake} non si è ancora concluso.
-  Questi socket sono tutti nello stato \texttt{SYN\_RECV}.
+  arrivato un SYN ma il \index{\textit{three~way~handshake}}\textit{three way
+    handshake} non si è ancora concluso.  Questi socket sono tutti nello stato
+  \texttt{SYN\_RECV}.
 \item La coda delle connessioni complete (\textit{complete connection queue}
-  che contiene un ingresso per ciascun socket per il quale il three way
-  handshake è stato completato ma ancora \func{accept} non è ritornata.
+  che contiene un ingresso per ciascun socket per il quale il \textit{three
+    way handshake} è stato completato ma ancora \func{accept} non è ritornata.
   Questi socket sono tutti nello stato \texttt{ESTABLISHED}.
 \end{enumerate}
 
@@ -909,12 +921,13 @@ Lo schema di funzionamento 
 quando arriva un SYN da un client il server crea una nuova voce nella coda
 delle connessioni incomplete, e poi risponde con il SYN$+$ACK. La voce 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
-la voce viene spostata nella coda delle connessioni complete.  Quando il
-processo chiama la funzione \func{accept} (vedi sez.~\ref{sec:TCP_func_accept})
-la prima voce 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.
+client o fino ad un timeout. Nel caso di completamento del
+\index{\textit{three~way~handshake}}\textit{three way handshake} la voce viene
+spostata nella coda delle connessioni complete.  Quando il processo chiama la
+funzione \func{accept} (vedi sez.~\ref{sec:TCP_func_accept}) la prima voce
+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.
 
 \begin{figure}[htb]
   \centering
@@ -924,7 +937,7 @@ della prima connessione completa.
   \label{fig:TCP_listen_backlog}
 \end{figure}
 
-Storicamente il valore del parametro \param{backlog} era corrispondente al
+Storicamente il valore dell'argomento \param{backlog} era corrispondente al
 massimo valore della somma del numero di voci possibili per ciascuna delle due
 code. Stevens in \cite{UNP1} riporta che BSD ha sempre applicato un fattore di
 1.5 a detto valore, e fornisce una tabella con i risultati ottenuti con vari
@@ -966,7 +979,7 @@ 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.
+\textit{three way handshake}\index{\textit{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
@@ -986,8 +999,8 @@ trasparente dal protocollo TCP.
 La funzione \funcd{accept} è chiamata da un server per gestire la connessione
 una volta che sia stato completato il \textit{three way
   handshake},\footnote{la funzione è comunque generica ed è utilizzabile su
-  socket di tipo \texttt{SOCK\_STREAM}, \texttt{SOCK\_SEQPACKET} e
-  \texttt{SOCK\_RDM}.} la funzione restituisce un nuovo socket descriptor su
+  socket di tipo \const{SOCK\_STREAM}, \const{SOCK\_SEQPACKET} e
+  \const{SOCK\_RDM}.} 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:
@@ -1176,13 +1189,13 @@ ritornata da \func{accept}), all'esecuzione di \func{exec} verr
 memoria l'immagine del programma eseguito, che a questo punto perde ogni
 riferimento ai valori tornati da \func{accept}.  Il socket descriptor però
 resta aperto, e se si è seguita una opportuna convenzione per rendere noto al
-programma eseguito qual'è il socket connesso, \footnote{ad esempio il solito
+programma eseguito qual è il socket connesso, \footnote{ad esempio il solito
   \cmd{inetd} 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.
 
 Infine è da chiarire (si legga la pagina di manuale) che, come per
-\func{accept}, il terzo parametro, che è specificato dallo standard POSIX.1g
+\func{accept}, il terzo argomento, 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.
@@ -1202,9 +1215,9 @@ 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 sez.~\ref{sec:TCP_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.
+Vedremo più avanti in sez.~\ref{sec:sock_generic_options} come sia possibile
+cambiare questo comportamento, e cosa può essere fatto perché il processo
+possa assicurarsi che l'altro capo abbia ricevuto tutti i dati.
 
 Come per tutti i file descriptor anche per i socket viene mantenuto un numero
 di riferimenti, per cui se più di un processo ha lo stesso socket aperto
@@ -1400,7 +1413,7 @@ marcare dei blocchi di dati, per cui se questo 
 programma stesso.
 
 Se abilitiamo il servizio \textit{daytime}\footnote{in genere questo viene
-  fornito direttamente dal \textsl{superdemone} \texttt{inetd}, pertanto basta
+  fornito direttamente dal \textsl{superdemone} \cmd{inetd}, pertanto basta
   assicurarsi che esso sia abilitato nel relativo file di configurazione.}
 possiamo verificare il funzionamento del nostro client, avremo allora:
 \begin{verbatim}
@@ -1454,7 +1467,7 @@ programma.
 Il passo successivo (\texttt{\small 35--39}) è quello di mettere ``in
 ascolto'' il socket; questo viene fatto (\texttt{\small 36}) con la funzione
 \func{listen} che dice al kernel di accettare connessioni per il socket che
-abbiamo creato; la funzione indica inoltre, con il secondo parametro, il
+abbiamo creato; la funzione indica inoltre, con il secondo argomento, il
 numero massimo di connessioni che il kernel accetterà di mettere in coda per
 il suddetto socket. Di nuovo in caso di errore si stampa (\texttt{\small 37})
 un messaggio, e si esce (\texttt{\small 38}) immediatamente.
@@ -1587,7 +1600,7 @@ Inoltre nel caso sia stato abilitato il \textit{logging} delle connessioni, si
 provvede anche (\texttt{\small 40--43}) a stampare sullo standard output
 l'indirizzo e la porta da cui il client ha effettuato la connessione, usando i
 valori contenuti nelle strutture restituite da \func{accept}, eseguendo le
-opportune conversioni con \func{inet\_ntop} e \func{atohs}.
+opportune conversioni con \func{inet\_ntop} e \func{ntohs}.
 
 Ancora una volta l'esempio è estremamente semplificato, si noti come di nuovo
 non si sia gestita né la terminazione del processo né il suo uso come demone,
@@ -1699,7 +1712,7 @@ sez.~\ref{sec:sock_io_behav}, per scrivere i dati sul socket, gestendo
 automaticamente l'invio multiplo qualora una singola \func{write} non sia
 sufficiente.  I dati vengono riletti indietro (\texttt{\small 7}) con una
 \func{read}\footnote{si è fatta l'assunzione implicita che i dati siano
-  contenuti tutti in un solo segmento, così che la chiamata a \texttt{read} li
+  contenuti tutti in un solo segmento, così che la chiamata a \func{read} li
   restituisca sempre tutti; avendo scelto una dimensione ridotta per il buffer
   questo sarà sempre vero, vedremo più avanti come superare il problema di
   rileggere indietro tutti e soli i dati disponibili, senza bloccarsi.} sul
@@ -1898,14 +1911,14 @@ connessioni da qualunque indirizzo e da qualunque porta e su qualunque
 interfaccia locale.
 
 A questo punto si può lanciare il client, esso chiamerà \func{socket} e
-\func{connect}; una volta completato il three way handshake la connessione è
-stabilita; la \func{connect} ritornerà nel client\footnote{si noti che è
-  sempre la \func{connect} del client a ritornare per prima, in quanto
-  questo avviene alla ricezione del secondo segmento (l'ACK del server) del
-  three way handshake, la \func{accept} del server ritorna solo dopo
-  un altro mezzo RTT quando il terzo segmento (l'ACK del client) viene
-  ricevuto.} e la \func{accept} nel server, ed usando di nuovo
-\cmd{netstat} otterremmo che:
+\func{connect}; una volta completato il \textit{three way handshake} la
+connessione è stabilita; la \func{connect} ritornerà nel client\footnote{si
+  noti che è sempre la \func{connect} del client a ritornare per prima, in
+  quanto questo avviene alla ricezione del secondo segmento (l'ACK del server)
+  del \textit{three way handshake}, la \func{accept} del server ritorna solo
+  dopo un altro mezzo RTT quando il terzo segmento (l'ACK del client) viene
+  ricevuto.}  e la \func{accept} nel server, ed usando di nuovo \cmd{netstat}
+otterremmo che:
 \begin{verbatim}
 Active Internet connections (servers and established)
 Proto Recv-Q Send-Q Local Address           Foreign Address         State
@@ -2152,7 +2165,7 @@ perch
 interrotta dall'arrivo di \const{SIGCHLD}, è quella ad \func{accept}, che è
 l'unica funzione che può mettere il processo padre in stato di sleep nel
 periodo in cui un figlio può terminare; si noti infatti come le altre
-\index{system call lente} \textit{slow system call}\footnote{si ricordi la
+\index{system~call~lente} \textit{slow system call}\footnote{si ricordi la
   distinzione fatta in sez.~\ref{sec:sig_gen_beha}.} o sono chiamate prima di
 entrare nel ciclo principale, quando ancora non esistono processi figli, o
 sono chiamate dai figli stessi e non risentono di \const{SIGCHLD}.
@@ -2248,13 +2261,14 @@ funzione \func{accept}.
 Benché questo non sia un fatto comune, un evento simile può essere osservato
 con dei server molto occupati. In tal caso, con una struttura del server
 simile a quella del nostro esempio, in cui la gestione delle singole
-connessioni è demandata a processi figli, può accadere che il three way
-handshake venga completato e la relativa connessione abortita subito dopo,
-prima che il padre, per via del carico della macchina, abbia fatto in tempo ad
-eseguire la chiamata ad \func{accept}. Di nuovo si ha una situazione analoga
-a quella illustrata in fig.~\ref{fig:TCP_early_abort}, in cui la connessione
-viene stabilita, ma subito dopo si ha una condizione di errore che la chiude
-prima che essa sia stata accettata dal programma.
+connessioni è demandata a processi figli, può accadere che il \textit{three
+  way handshake}\index{\textit{three~way~handshake}} venga completato e la
+relativa connessione abortita subito dopo, prima che il padre, per via del
+carico della macchina, abbia fatto in tempo ad eseguire la chiamata ad
+\func{accept}. Di nuovo si ha una situazione analoga a quella illustrata in
+fig.~\ref{fig:TCP_early_abort}, in cui la connessione viene stabilita, ma
+subito dopo si ha una condizione di errore che la chiude prima che essa sia
+stata accettata dal programma.
 
 Questo significa che, oltre alla interruzione da parte di un segnale, che
 abbiamo trattato in sez.~\ref{sec:TCP_child_hand} nel caso particolare di
@@ -2278,9 +2292,10 @@ attraverso la sequenza vista in sez.~\ref{sec:TCP_conn_term}, per cui la
 \func{accept} ritornerà senza errori, e si avrà semplicemente un end-of-file
 al primo accesso al socket. Nel caso di Linux inoltre, anche qualora si
 modifichi il client per fargli gestire l'invio di un segmento di RST alla
-chiusura dal socket (come suggerito da Stevens in \cite{UNP1}), non si ha
-nessun errore al ritorno di \funcd{accept}, quanto un errore di
-\errcode{ECONNRESET} al primo tentativo di accesso al socket.
+chiusura dal socket (usando l'opzione \const{SO\_LINGER}, vedi
+sez.~\ref{sec:sock_options_main}), non si ha nessun errore al ritorno di
+\func{accept}, quanto un errore di \errcode{ECONNRESET} al primo tentativo di
+accesso al socket.
 
 
 
@@ -2357,14 +2372,15 @@ anarres.echo > gont.34559: R 511689732:511689732(0) win 0
 \end{verbatim}
 
 Le prime tre righe vengono prodotte al momento in cui lanciamo il nostro
-client, e corrispondono ai tre pacchetti del three way handshake. L'output del
-comando riporta anche i numeri di sequenza iniziali, mentre la lettera
-\texttt{S} indica che per quel pacchetto si aveva il SYN flag attivo. Si noti
+client, e corrispondono ai tre pacchetti del
+\index{\textit{three~way~handshake}}\textit{three way handshake}.  L'output
+del comando riporta anche i numeri di sequenza iniziali, mentre la lettera
+\texttt{S} indica che per quel pacchetto si aveva il SYN flag attivo.  Si noti
 come a partire dal secondo pacchetto sia sempre attivo il campo \texttt{ack},
 seguito dal numero di sequenza per il quale si da il ricevuto; quest'ultimo, a
 partire dal terzo pacchetto, viene espresso in forma relativa per maggiore
 compattezza.  Il campo \texttt{win} in ogni riga indica la \textit{advertising
-  window} di cui parlavamo in sez.~\ref{sec:TCP_TCP_opt}. Allora si può
+  window} di cui parlavamo in sez.~\ref{sec:TCP_TCP_opt}.  Allora si può
 verificare dall'output del comando come venga appunto realizzata la sequenza
 di pacchetti descritta in sez.~\ref{sec:TCP_conn_cre}: prima viene inviato dal
 client un primo pacchetto con il SYN che inizia la connessione, a cui il
@@ -2372,16 +2388,17 @@ server risponde dando il ricevuto con un secondo pacchetto, che a sua volta
 porta un SYN, cui il client risponde con un il terzo pacchetto di ricevuto.
 
 Ritorniamo allora alla nostra sessione con il servizio echo: dopo le tre righe
-del three way handshake non avremo nulla fin tanto che non scriveremo una
-prima riga sul client; al momento in cui facciamo questo si genera una
-sequenza di altri quattro pacchetti. Il primo, dal client al server,
-contraddistinto da una lettera \texttt{P} che significa che il flag PSH è
-impostato, contiene la nostra riga (che è appunto di 11 caratteri), e ad esso
-il server risponde immediatamente con un pacchetto vuoto di ricevuto. Poi
-tocca al server riscrivere indietro quanto gli è stato inviato, per cui sarà
-lui a mandare indietro un terzo pacchetto con lo stesso contenuto appena
-ricevuto, e a sua volta riceverà dal client un ACK nel quarto pacchetto.
-Questo causerà la ricezione dell'eco nel client che lo stamperà a video.
+del \textit{three way handshake}\index{\textit{three~way~handshake}} non
+avremo nulla fin tanto che non scriveremo una prima riga sul client; al
+momento in cui facciamo questo si genera una sequenza di altri quattro
+pacchetti. Il primo, dal client al server, contraddistinto da una lettera
+\texttt{P} che significa che il flag PSH è impostato, contiene la nostra riga
+(che è appunto di 11 caratteri), e ad esso il server risponde immediatamente
+con un pacchetto vuoto di ricevuto. Poi tocca al server riscrivere indietro
+quanto gli è stato inviato, per cui sarà lui a mandare indietro un terzo
+pacchetto con lo stesso contenuto appena ricevuto, e a sua volta riceverà dal
+client un ACK nel quarto pacchetto.  Questo causerà la ricezione dell'eco nel
+client che lo stamperà a video.
 
 A questo punto noi procediamo ad interrompere l'esecuzione del server con un
 \texttt{C-c} (cioè con l'invio di \const{SIGTERM}): nel momento in cui
@@ -2425,13 +2442,13 @@ di RST, contraddistinto dalla lettera \texttt{R}, che causa la conclusione
 definitiva della connessione anche nel client, dove non comparirà più
 nell'output di \cmd{netstat}.
 
-Come abbiamo accennato in sez.~\ref{sec:TCP_conn_term} e come vedremo più avanti
-in sez.~\ref{sec:TCP_shutdown} la chiusura di un solo capo di un socket è
-una operazione lecita, per cui la nostra scrittura avrà comunque successo
+Come abbiamo accennato in sez.~\ref{sec:TCP_conn_term} e come vedremo più
+avanti in sez.~\ref{sec:TCP_shutdown} la chiusura di un solo capo di un socket
+è una operazione lecita, per cui la nostra scrittura avrà comunque successo
 (come si può constatare lanciando usando \cmd{strace}\footnote{il comando
-  \cmd{strace} è un comando di debug molto utile che prende come parametro un
+  \cmd{strace} è un comando di debug molto utile che prende come argomento un
   altro comando e ne stampa a video tutte le invocazioni di una system call,
-  coi relativi parametri e valori di ritorno, per cui usandolo in questo
+  coi relativi argomenti e valori di ritorno, per cui usandolo in questo
   contesto potremo verificare che effettivamente la \func{write} ha scritto la
   riga, che in effetti è stata pure trasmessa via rete.}), in quanto il nostro
 programma non ha a questo punto alcun modo di sapere che dall'altra parte non
@@ -2581,15 +2598,15 @@ successivo, per tentare di ristabilire la connessione.
 Il risultato finale qui dipende dall'implementazione dello stack TCP, e nel
 caso di Linux anche dall'impostazione di alcuni dei parametri di sistema che
 si trovano in \file{/proc/sys/net/ipv4}, che ne controllano il comportamento:
-in questo caso in particolare da \file{tcp\_retries2}. Questo parametro
-infatti specifica il numero di volte che deve essere ritentata la
-ritrasmissione di un pacchetto nel mezzo di una connessione prima di riportare
-un errore di timeout.  Il valore preimpostato è pari a 15, il che
-comporterebbe 15 tentativi di ritrasmissione, ma nel nostro caso le cose sono
-andate diversamente, dato che le ritrasmissioni registrate da \cmd{tcpdump}
-sono solo 8; inoltre l'errore riportato all'uscita del client non è stato
-\errcode{ETIMEDOUT}, come dovrebbe essere in questo caso, ma
-\errcode{EHOSTUNREACH}.
+in questo caso in particolare da \file{tcp\_retries2} (vedi
+sez.~\ref{sec:sock_sysctl}). Questo parametro infatti specifica il numero di
+volte che deve essere ritentata la ritrasmissione di un pacchetto nel mezzo di
+una connessione prima di riportare un errore di timeout.  Il valore
+preimpostato è pari a 15, il che comporterebbe 15 tentativi di ritrasmissione,
+ma nel nostro caso le cose sono andate diversamente, dato che le
+ritrasmissioni registrate da \cmd{tcpdump} sono solo 8; inoltre l'errore
+riportato all'uscita del client non è stato \errcode{ETIMEDOUT}, come dovrebbe
+essere in questo caso, ma \errcode{EHOSTUNREACH}.
 
 Per capire l'accaduto continuiamo ad analizzare l'output di \cmd{tcpdump}:
 esso ci mostra che a un certo punto i tentativi di ritrasmissione del
@@ -2700,7 +2717,7 @@ riportando appunto come errore \errcode{ECONNRESET}. Occorre precisare che se
 si vuole che il client sia in grado di accorgersi del crollo del server anche
 quando non sta effettuando uno scambio di dati, è possibile usare una
 impostazione speciale del socket (ci torneremo in
-sez.~\ref{sec:TCP_sock_options}) che provvede all'esecuzione di questo
+sez.~\ref{sec:sock_generic_options}) che provvede all'esecuzione di questo
 controllo.
 
 \section{L'uso dell'I/O multiplexing}
@@ -2748,8 +2765,8 @@ pronto per la lettura sono le seguenti:
   sufficiente a superare il valore di una \textsl{soglia di basso livello} (il
   cosiddetto \textit{low watermark}). Questo valore è espresso in numero di
   byte e può essere impostato con l'opzione del socket \const{SO\_RCVLOWAT}
-  (tratteremo le opzioni dei socket in sez.~\ref{sec:TCP_sock_options}); il
-  suo valore di default è 1 per i socket TCP e UDP. In questo caso una
+  (tratteremo l'uso di questa opzione in sez.~\ref{sec:sock_generic_options});
+  il suo valore di default è 1 per i socket TCP e UDP. In questo caso una
   operazione di lettura avrà successo e leggerà un numero di byte maggiore di
   zero.
 \item il lato in lettura della connessione è stato chiuso; si è cioè ricevuto
@@ -2761,7 +2778,7 @@ pronto per la lettura sono le seguenti:
 \item c'è stato un errore sul socket. In questo caso una operazione di lettura
   non si bloccherà ma restituirà una condizione di errore (ad esempio
   \func{read} restituirà -1) e imposterà la variabile \var{errno} al relativo
-  valore. Vedremo in sez.~\ref{sec:TCP_sock_options} come sia possibile
+  valore. Vedremo in sez.~\ref{sec:sock_generic_options} come sia possibile
   estrarre e cancellare errori pendenti su un socket usando l'opzione
   \const{SO\_ERROR}.
 \item quando si sta utilizzando un \textit{listening socket} ed ci sono delle
@@ -2782,8 +2799,9 @@ pronto per la scrittura sono le seguenti:
   valore della \textsl{soglia di basso livello} in scrittura ed inoltre o il
   socket è già connesso o non necessita (ad esempio è UDP) di connessione.  Il
   valore della soglia è espresso in numero di byte e può essere impostato con
-  l'opzione del socket \const{SO\_SNDLOWAT}; il suo valore di default è 2048
-  per i socket TCP e UDP. In questo caso una operazione di scrittura non si
+  l'opzione del socket \const{SO\_SNDLOWAT} (trattata in
+  sez.~\ref{sec:sock_generic_options}); il suo valore di default è 2048 per i
+  socket TCP e UDP. In questo caso una operazione di scrittura non si
   bloccherà e restituirà un valore positivo pari al numero di byte accettati
   dal livello di trasporto.
 \item il lato in scrittura della connessione è stato chiuso. In questo caso
@@ -2791,7 +2809,7 @@ pronto per la scrittura sono le seguenti:
 \item c'è stato un errore sul socket. In questo caso una operazione di
   scrittura non si bloccherà ma restituirà una condizione di errore ed
   imposterà opportunamente la variabile \var{errno}. Vedremo in
-  sez.~\ref{sec:TCP_sock_options} come sia possibile estrarre e cancellare
+  sez.~\ref{sec:sock_generic_options} come sia possibile estrarre e cancellare
   errori pendenti su un socket usando l'opzione \const{SO\_ERROR}.
 \end{itemize*}
 
@@ -3240,7 +3258,7 @@ che ci servir
 connessioni o di dati in arrivo, e processarli immediatamente. Per
 implementare lo schema mostrato in fig.~\ref{fig:TCP_echo_multiplex}, il
 programma usa una tabella dei socket connessi mantenuta nel vettore
-\var{fd\_open} dimensionato al valore di \macro{FD\_SETSIZE}, ed una variabile
+\var{fd\_open} dimensionato al valore di \const{FD\_SETSIZE}, ed una variabile
 \var{max\_fd} per registrare il valore più alto dei file descriptor aperti.
 
 Prima di entrare nel ciclo principale (\texttt{\small 6--56}) la nostra
@@ -3400,9 +3418,9 @@ condizioni della rete. Inoltre deve essere specificato come viene classificato
 il traffico nella suddivisione fra dati normali e prioritari. In generale
 pertanto:
 \begin{itemize}
-\item i dati trasmessi su un socket vengono considerati traffico normale,
-  pertanto vengono rilevati da una selezione con \const{POLLIN} o
-  \const{POLLRDNORM}.
+\item i dati inviati su un socket vengono considerati traffico normale,
+  pertanto vengono rilevati alla loro ricezione sull'altro capo da una
+  selezione effettuata con \const{POLLIN} o \const{POLLRDNORM};
 \item i dati \textit{out-of-band} su un socket TCP vengono considerati
   traffico prioritario e vengono rilevati da una condizione \const{POLLIN},
   \const{POLLPRI} o \const{POLLRDBAND}.
@@ -3410,6 +3428,10 @@ pertanto:
   viene considerato traffico normale, pertanto viene rilevato da una
   condizione \const{POLLIN} o \const{POLLRDNORM}, ma una conseguente chiamata
   a \func{read} restituirà 0.
+\item la disponibilità di spazio sul socket per la scrittura di dati viene
+  segnalata con una condizione \const{POLLOUT}.
+\item quando uno dei due capi del socket chiude un suo lato della connessione
+  con \func{shutdown} si riceve una condizione di \const{POLLHUP}.
 \item la presenza di un errore sul socket (sia dovuta ad un segmento RST che a
   timeout) viene considerata traffico normale, ma viene segnalata anche dalla
   condizione \const{POLLERR}.