Aggiunto l'header nell'environment per scrivere i prototipi delle funzioni e
[gapil.git] / elemtcp.tex
index 5e5a69cd3c782f2cda80f1e40a864c79352e8d58..ca1a94b3562ba63454d58d278a53beda70dc3ede 100644 (file)
@@ -634,10 +634,10 @@ cio
 server per specificare la porta (e gli eventuali indirizzi locali) su cui poi
 ci si porrà in ascolto.
 
-Il prototipo della funzione, definito in \texttt{sys/socket.h}, è il seguente:
+Il prototipo della funzione è il seguente:
 
-\begin{prototype}{int bind(int sockfd, const struct sockaddr *serv\_addr,
-    socklen\_t addrlen) }
+\begin{prototype}{sys/socket.h}
+{int bind(int sockfd, const struct sockaddr *serv\_addr, socklen\_t addrlen)}
   
   Il primo argomento è un file descriptor ottenuto da una precedente chiamata
   a \texttt{socket}, mentre il secondo e terzo argomento sono rispettivamente
@@ -713,11 +713,10 @@ di effettuare una assegnazione del tipo:
 \label{sec:TCPel_func_connect}
 
 La funzione \texttt{connect} è usata da un client TCP per stabilire la
-connessione con un server TCP, il prototipo della funzione, definito in
-\texttt{sys/socket.h}, è il seguente:
+connessione con un server TCP, il prototipo della funzione è il seguente:
 
-\begin{prototype}{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
@@ -819,9 +818,20 @@ necessario effettuare una \texttt{bind}.
 La funzione \texttt{listen} è usata per usare un socket in modalità passiva,
 cioè, come dice il nome, per metterlo in ascolto di eventuali connessioni; in
 sostanza l'effetto della funzione è di portare il socket dallo stato
-\texttt{CLOSED} a quello \texttt{LISTEN}.
+\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}{int listen(int sockfd, int backlog)}
+\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 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.
@@ -832,6 +842,66 @@ sostanza l'effetto della funzione 
 \end{prototype}
 
 
+Il parametro \texttt{backlog} indica il numero massimo di connessioni pendenti
+accettate; se esso viene ecceduto il client riceverà una errore di tipo
+\texttt{ECONNREFUSED}, o se il protocollo, come nel caso del TCP, supporta la
+ritrasmissione, la richiesta sarà ignorata in modo che la connessione possa
+essere ritentata.
+
+Per capire meglio il significato di tutto ciò occorre approfondire la modalità
+con cui il kernel tratta le connessioni in arrivo. Per ogni socket in ascolto
+infatti vengono mantenute due code:
+\begin{enumerate}
+\item Una coda delle connessioni incomplete (\textit{incomplete connection
+    queue} che contiene una entrata per ciascun SYN arrivato per il quale si
+  sta attendendo la conclusione del three-way handshake. Questi socket sono
+  tutti nello stato \texttt{SYN\_RECV}.
+\item Una coda delle connessioni complete (\textit{complete connection queue}
+  che contiene una entrata per ciascuna connessione per le quali il three-way
+  handshake è stato completato ma ancora \texttt{accept} non è ritornata.
+\end{enumerate}
+
+Lo schema di funzionamento è descritto in \nfig, quando arriva un SYN da un
+client il server crea una nuova entrata nella coda delle connessioni
+incomplete, e poi risponde con il SYN$+$ACK. La entrata resterà nella coda
+delle connessioni incomplete fino al ricevimento dell'ACK dal client o fino ad
+un timeout. Nel caso di completamento del three-way handshake l'entrata viene
+sostata nella coda delle connessioni complete. Quando il processo chiama la
+funzione \texttt{accept} (vedi \secref{sec:TCPel_func_accept}) la prima
+entrata nella coda delle connessioni complete è passata al programma, o, se la
+coda è vuota, il processo viene posto in attesa e risvegliato all'arrivo della
+prima connessione completa.
+
+Storicamente il valore del parametro \texttt{backlog} era corrispondente al
+massimo valore della somma del numero di entrate possibili per ciascuna di
+dette code. Stevens riporta che BSD ha sempre applicato un fattore di 1.5 al
+valore, e provvede una tabella con i risultati ottenuti con vari kernel,
+compreso linux 2.0, che mostrano le differenze fra diverse implementazioni.
+
+Ma in linux il significato di questo valore è cambiato a partire dal kernel
+2.2 per prevenire l'attacco chiamato \texttt{syn flood}. Questo si basa
+sull'emissione da parte dell'attaccante di un grande numero di pacchetti SYN
+indirizzati verso una porta forgiati con indirizzo IP fasullo \footnote{con la
+  tecnica che viene detta \textit{ip spoofing}} così che i SYN$+$ACK vanno
+perduti la coda delle connessioni incomplete viene saturata, impedendo di
+fatto le connessioni.
+
+Per ovviare a questo il significato del \texttt{backlog} è stato cambiato a
+significare la lunghezza della coda delle connessioni complete. La lunghezza
+della coda delle connessioni incomplete può essere ancora controllata usando
+la \texttt{sysctl} o scrivendola direttamente in
+\texttt{/proc/sys/net/ipv4/tcp\_max\_syn\_backlog}. Quando si attiva la
+protezione dei syncookies però (con l'opzione da compilare nel kernel e da
+attivare usando \texttt{/proc/sys/net/ipv4/tcp\_syncookies}) questo valore
+viene ignorato e non esiste più un valore massimo.
+
+La scelta storica per il valore di questo parametro è di 5, e alcuni vecchi
+kernel non supportavano neanche valori superiori, ma la situazione corrente è
+molto cambiata dagli anni '80 e con server web che possono sopportare diversi
+milioni di connessioni al giorno un tale valore non è più adeguato. Non esiste
+comunque una risposta univoca 
+
+
 
 \subsection{La funzione \texttt{accept}}
 \label{sec:TCPel_func_accept}