X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=tcpsock.tex;h=14c664b9949cd98a88675f055fd76738bc7b4136;hp=aaa79147d819a60c1c9cebb0bbb6f027a09547e7;hb=6f8e0ca42d3d0b97b5e5747798a1eaffb44e8521;hpb=bf81ce9ec539254693a8c41641a99af1aa1d886f diff --git a/tcpsock.tex b/tcpsock.tex index aaa7914..14c664b 100644 --- a/tcpsock.tex +++ b/tcpsock.tex @@ -38,7 +38,7 @@ 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}|(} +\itindbeg{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 @@ -86,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] @@ -118,7 +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}|)} + +\itindend{three~way~handshake} \subsection{Le opzioni TCP.} @@ -136,7 +137,8 @@ regolare la connessione. Normalmente vengono usate le seguenti opzioni: connessione corrente. È possibile leggere e scrivere questo valore attraverso l'opzione del socket \const{TCP\_MAXSEG}. -\item \textit{window scale option}, %come spiegato in sez.~\ref{sec:tcp_protocol} +\item \textit{window scale + option}, %come spiegato in sez.~\ref{sec: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 @@ -271,7 +273,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 @@ -392,7 +394,7 @@ una connessione fra due router si interrompa. In questo caso i protocolli di instradamento dei pacchetti possono impiegare diverso tempo (anche dell'ordine dei minuti) prima di trovare e stabilire un percorso alternativo per i pacchetti. Nel frattempo possono accadere casi in cui un router manda i -pacchetti verso un'altro e quest'ultimo li rispedisce indietro, o li manda ad +pacchetti verso un altro e quest'ultimo li rispedisce indietro, o li manda ad un terzo router che li rispedisce al primo, si creano cioè dei circoli (i cosiddetti \textit{routing loop}) in cui restano intrappolati i pacchetti. @@ -461,17 +463,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 @@ -483,29 +485,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 @@ -613,17 +622,17 @@ tcp 0 0 195.110.112.152:22 192.84.146.100:21100 ESTABLISHED tcp 0 0 195.110.112.152:22 192.84.146.100:21101 ESTABLISHED \end{verbatim} cioè il client effettuerà la connessione usando un'altra porta effimera: con -questa sarà aperta la connessione, ed il server creerà un'altro processo +questa sarà aperta la connessione, ed il server creerà un altro processo figlio per gestirla. Tutto ciò mostra come il 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\footnote{ad esempio con il comando \cmd{fuser}, o con \cmd{lsof}.} 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. +processi\footnote{ad esempio con il comando \cmd{fuser}, o con \cmd{lsof}, o + usando l'opzione \texttt{-p}.} 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 di base per la gestione dei socket} @@ -641,7 +650,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: @@ -709,7 +718,7 @@ 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}\index{\textit{endianess}} della macchina, ed anche se +l'\textit{endianess}\itindex{endianess} della macchina, ed anche se esse possono essere invarianti rispetto all'ordinamento dei bit, è comunque buona norma usare sempre la funzione \func{htonl}. @@ -739,10 +748,10 @@ con una struttura, perch costante come operando a destra in una assegnazione. Per questo motivo nell'header \file{netinet/in.h} è definita una variabile -\const{in6addr\_any} (dichiarata come \direct{extern}, ed inizializzata dal +\macro{in6addr\_any} (dichiarata come \direct{extern}, ed inizializzata dal sistema al valore \const{IN6ADRR\_ANY\_INIT}) che permette di effettuare una assegnazione del tipo: \includecodesnip{listati/serv_addr_sin6_addr.c} in -maniera analoga si può utilizzare la variabile \const{in6addr\_loopback} per +maniera analoga si può utilizzare la variabile \macro{in6addr\_loopback} per indicare l'indirizzo di \textit{loopback}, che a sua volta viene inizializzata staticamente a \const{IN6ADRR\_LOOPBACK\_INIT}. @@ -754,12 +763,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 \index{\textit{three~way~handshake}}\textit{three way handshake}) - 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 \itindex{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)} @@ -802,7 +811,7 @@ 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 -\index{\textit{three~way~handshake}}\textit{three way handshake}, e ritorna +\itindex{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 @@ -810,7 +819,7 @@ 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 - di \func{connect}, un'altro dopo 6 secondi, un terzo dopo 24 secondi, se + di \func{connect}, un altro dopo 6 secondi, un terzo dopo 24 secondi, se dopo 75 secondi non ha ricevuto risposta viene ritornato l'errore. Linux invece ripete l'emissione del SYN ad intervalli di 30 secondi per un numero di volte che può essere stabilito dall'utente sia con una opportuna @@ -818,10 +827,7 @@ o problemi nella chiamata della funzione sono le seguenti: voluto in \file{/proc/sys/net/ipv4/tcp\_syn\_retries}. Il valore predefinito per la ripetizione dell'invio è di 5 volte, che comporta un timeout dopo circa 180 secondi. -% -% Le informazioni su tutte le opzioni impostabili via /proc stanno in -% Linux/Documentation/networking/ip-sysctl.txt -% + \item Il client riceve come risposta al SYN un RST significa che non c'è nessun programma in ascolto per la connessione sulla porta specificata (il che vuol dire probabilmente che o si è sbagliato il numero della porta o che @@ -864,8 +870,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 @@ -901,7 +907,7 @@ 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 \index{\textit{three~way~handshake}}\textit{three way + arrivato un SYN ma il \itindex{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} @@ -915,7 +921,7 @@ 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 -\index{\textit{three~way~handshake}}\textit{three way handshake} la voce viene +\itindex{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 è @@ -972,7 +978,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 -\textit{three way handshake}\index{\textit{three~way~handshake}}. +\textit{three way handshake}\itindex{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 @@ -990,10 +996,10 @@ trasparente dal protocollo TCP. \label{sec:TCP_func_accept} 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 +una volta che sia stato completato il \itindex{three~way~handshake} +\textit{three way handshake},\footnote{la funzione è comunque generica ed è + utilizzabile 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: @@ -1182,7 +1188,7 @@ 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. @@ -1406,7 +1412,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} @@ -1593,7 +1599,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, @@ -1705,7 +1711,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 @@ -1785,7 +1791,7 @@ processo ad un gruppo senza privilegi,\footnote{si 27--30}) l'operazione usando \func{setuid} per cambiare anche l'utente.\footnote{si tenga presente che l'ordine in cui si eseguono queste due operazioni è importante, infatti solo avendo i privilegi di - amministratore si può cambiare il gruppo di un processo ad un'altro di cui + amministratore si può cambiare il gruppo di un processo ad un altro di cui non si fa parte, per cui chiamare prima \func{setuid} farebbe fallire una successiva chiamata a \func{setgid}. Inoltre si ricordi (si riveda quanto esposto in sez.~\ref{sec:proc_perms}) che usando queste due funzioni il @@ -1904,14 +1910,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 \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: +\func{connect}; una volta completato il \itindex{three~way~handshake} +\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 @@ -2255,10 +2261,10 @@ Bench 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 \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 + way handshake}\itindex{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. @@ -2285,9 +2291,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. @@ -2365,8 +2372,8 @@ anarres.echo > gont.34559: R 511689732:511689732(0) win 0 Le prime tre righe vengono prodotte al momento in cui lanciamo il nostro 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 +\itindex{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 @@ -2380,17 +2387,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 \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. +del \textit{three way handshake}\itindex{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 @@ -3250,7 +3257,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